2010-12-08 11 views
10

Hola,¿Qué significa que se 'abortó' el hilo? 'en SNIReadSync (SNI_Conn *, SNI_Packet **, Int32)' significa?

tengo la excepción abajo en una aplicación web ASP.Net (utilizando SQL-Server 2008), cuando se procesa una gran cantidad de datos - y parece que esta excepción se produce en una ubicación aleatoria en el código .

¿Qué significa esta excepción? ¿Es un tiempo de espera?

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 

¡Gracias!

+3

¿Su código llama 'Response.End' o' Response.Redirect' en cualquier punto? –

+0

Estoy obteniendo exactamente el mismo error y sí, estoy usando datos grandes también – sino

Respuesta

3

"Se estaba cancelando el subproceso" los errores son, el 99% del tiempo, causados ​​por el uso de Thread.Abort() de su código para finalizar un proceso en cualquier otra circunstancia que falla catastrófica. Thread.Abort es malo, porque inyecta una excepción en el hilo desde fuera de su propio código de ejecución y, por lo tanto, es extremadamente difícil, incluso imposible, esperarlo y manejarlo con elegancia.

Si está ejecutando este código en otro hilo (buena opción por cierto, las operaciones DB son un candidato natural para el multihilo), NO use Thread.Abort() para intentar controlar el hilo. En su lugar, debe construir el código del subproceso para que responda a algún cambio externo que pueda desencadenar, lo que hará que finalice con elegancia el proceso. Aquí hay un ejemplo simple:

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"); 
    } 
} 

Este ejemplo utiliza una lambda con un "cierre externo"; si nuestro método fuera a salir antes de que se complete el subproceso de trabajo, el lambda generaría un error debido a que la variable cancel fue descartada y destruida. Solo tenga en cuenta este tipo de cosas cuando adapte este modelo a su arquitectura real; si está iniciando el hilo en un método y esperando que termine en otro, mientras desencadena la cancelación en un tercero (una circunstancia bastante común en realidad), la bandera debe vivir en algún lugar donde no se destruirá antes de que el hilo de trabajo tenga finalizó la ejecución.

+0

gracias, pero no usé 'Thread.Abort()' en mi código ... – user4531

+3

mirando la stacktrace: si Thread.Abort() está siendo llamado se llama en SNINativeMethodWrapper.SNIReadSync que me parece un método de marco por lo que su respuesta no es útil – nflash