2010-12-08 57 views
10

Hallo,什麼是'線程被中止'。 '在SNIReadSync(SNI_Conn *,SNI_Packet **,Int32)'是什麼意思?

當我處理大量數據時,我在ASP.Net WebApp(使用SQL-Server 2008)中得到了下面的異常 - 而且看起來這個異常拋出在代碼中的一個隨機位置。

這個例外是什麼意思?它是否超時?

Thread was being aborted. 
    at SNIReadSync(SNI_Conn* , SNI_Packet** , Int32) 
at SNINativeMethodWrapper.SNIReadSync(SafeHandle pConn, IntPtr& packet, Int32 timeout) 
at System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult, TdsParserStateObject stateObj) 
at System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket() 
at System.Data.SqlClient.TdsParserStateObject.ReadBuffer() 
at System.Data.SqlClient.TdsParserStateObject.ReadByte() 
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) 
at System.Data.SqlClient.SqlDataReader.ConsumeMetaData() 
at System.Data.SqlClient.SqlDataReader.get_MetaData() 
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) 
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) 
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) 
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) 
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) 
at System.Data.SqlClient.SqlCommand.Exec 

謝謝!

+3

您的代碼是否在任何時候調用`Response.End`或`Response.Redirect`? – 2010-12-08 16:38:22

+0

我得到完全相同的錯誤,是的,我也使用大數據 – sino 2013-04-25 18:43:48

回答

3

「線程被中止」的錯誤是99%的時間,由於使用代碼中的Thread.Abort()來結束進程而不是發生災難性故障。 Thread.Abort是邪惡的,因爲它從它自己的執行代碼之外向線程注入異常,因此期望並優雅地處理它是極其困難的,甚至是不可能的。

如果您在另一個線程中運行此代碼(很好的選擇,BTW;數據庫操作是多線程的自然候選),請勿使用Thread.Abort()來嘗試控制線程。您應該構建線程的代碼以響應您可以觸發的某些外部更改,這將導致它正常結束處理。這裏有一個簡單的例子:

public class Foo 
{ 
    public void MainMethod() 
    { 
     bool cancel = false; //our external flag 

     //our worker thread, which is being given a callback method to poll at "safe" times. 
     var workerThread = new Thread(()=>AsyncMethod(()=>cancel)); 
     //start the thread 
     workerThread.Start(); 
     //do some other work that takes less time than the thread 
     Thread.Sleep(200) 
     //async thread is still going; cancel execution and wait for graceful exit. 
     cancel = true; 
     workerThread.Join(); 
    } 

    public void AsyncMethod(Func<bool> wasCancelled) 
    { 
     //Do some repetitive task that takes longer than we're willing to wait 
     for(var i=1; i<2000; i++) 
     { 
      if(wasCancelled()) break; //generally a "safe" place to check 
      Thread.Sleep(50); //stand-in for some atomic operation that should not be interrupted. 
     } 

     if(wasCancelled()) 
      Debug.WriteLine("Thread cancelled"); 
     else 
      Debug.WriteLine("Thread completed"); 
    } 
} 

這個例子確實使用了帶有「外部閉包」的lambda;如果我們的方法要在工作線程完成之前退出,那麼lambda會出錯,因爲取消變量已被取消範圍並被銷燬。在將此模型適用於實際架構時,請牢記這些事情;如果你在一個方法中啓動線程並等待它在另一個方法中完成,而在第三個觸發取消(實際上是一個相當常見的情況)時,該標誌必須存在於工作者線程沒有被銷燬之前的某個地方最終執行。