【问题标题】:What does 'Thread was being aborted.' 'at SNIReadSync(SNI_Conn* , SNI_Packet** , Int32 )' mean?'Thread was being aborted.' 是什么意思? '在 SNIReadSync(SNI_Conn* , SNI_Packet** , Int32 )' 是什么意思?
【发布时间】:2010-12-08 16:07:19
【问题描述】:

你好,

当处理大量数据时,我在 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

谢谢!

【问题讨论】:

  • 您的代码是否在任何时候调用Response.EndResponse.Redirect
  • 我得到完全相同的错误,是的,我也在使用大数据

标签: asp.net sql-server


【解决方案1】:

“线程被中止”错误在 99% 的情况下是由使用代码中的 Thread.Abort() 在除灾难性故障之外的任何其他情况下结束进程引起的。 Thread.Abort 是邪恶的,因为它从自己的执行代码之外将异常注入线程,因此很难,甚至不可能期望并优雅地处理它。

如果您在另一个线程中运行此代码(顺便说一句,这是一个不错的选择;DB 操作是多线程的自然候选者),请勿使用 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 将出错,因为取消变量被取消作用域并被销毁。在将此模型应用于您的实际架构时,请记住这些事情;如果您以一种方法启动线程并等待它在另一种方法中完成,同时在第三种方法中触发取消(实际上是一种相当常见的情况),则标志必须位于在工作线程之前不会被销毁的地方结束执行。

【讨论】:

  • 查看堆栈跟踪:如果在 SNINativeMethodWrapper.SNIReadSync 中调用了 Thread.Abort(),这在我看来是一种框架方法,因此您的回答没有帮助
猜你喜欢
  • 1970-01-01
  • 2011-08-12
  • 2017-06-11
  • 2018-03-05
  • 2023-03-27
  • 1970-01-01
  • 2016-08-17
  • 2010-12-28
  • 1970-01-01
相关资源
最近更新 更多