C# 多线程|线程正在中止

C# 多线程|线程正在中止,c#,multithreading,thread-safety,C#,Multithreading,Thread Safety,我们正在3-4个不同的线程中运行一个长作业(函数)。所有正在运行的线程都已成功完成,但有时异常线程被中止由其中一个线程引发,从而导致所有线程停止。下面是我们在应用程序中实际执行的操作的示例代码 List<Thread> lstThreads = new List<Thread>(); foreach(int 0; i < 4; i++) { Thread th = new Thread(() => { RunLongRunningJob(i);

我们正在3-4个不同的线程中运行一个长作业(函数)。所有正在运行的线程都已成功完成,但有时异常
线程被中止
由其中一个线程引发,从而导致所有线程停止。下面是我们在应用程序中实际执行的操作的示例代码

List<Thread> lstThreads = new List<Thread>();
foreach(int 0; i < 4; i++)
{
  Thread th = new Thread(() => {
    RunLongRunningJob(i);
  });
  lstThreads.Add(th);
}
foreach (Thread th in lstThreads)
  th.Start();
List lsthreads=new List();
foreach(int 0;i<4;i++)
{
线程th=新线程(()=>{
RunningJob(i);
});
添加(th);
}
foreach(螺纹中的th螺纹)
th.Start();
我们正在调用RESTAPI,在
RunLongRunningJob
中写入文件并更新数据库记录

另外,我们没有使用锁,这可能是原因吗?

在C#中,线程不能完全停止而没有副作用。想象一下,线程已经准备好了一次性物品,只是停止了。作为一种解决方法,当线程被中止时(您不应该这样做,但可以调用thread对象),将生成并执行ThreadAbortException。这允许异常处理启动并关闭文件句柄等

啊,终于找到了-这是一篇博客文章,解释了为什么不应该调用Thread.Abort(即应用程序代码不应该调用它):

这是关于计时和线程在非常糟糕的情况下最终不能正确执行的问题

现在,必须找出导致线程中止的原因。这是需要检查的内容-异常详细信息会有所帮助,包括堆栈跟踪和其中可能存在的内部异常。

在C#中,如果没有副作用,线程根本无法停止。想象一下,线程已经准备好了一次性物品,只是停止了。作为一种解决方法,当线程被中止时(您不应该这样做,但可以调用thread对象),将生成并执行ThreadAbortException。这允许异常处理启动并关闭文件句柄等

啊,终于找到了-这是一篇博客文章,解释了为什么不应该调用Thread.Abort(即应用程序代码不应该调用它):

这是关于计时和线程在非常糟糕的情况下最终不能正确执行的问题


现在,必须找出导致线程中止的原因。这是需要检查的内容-异常详细信息会有所帮助,包括堆栈跟踪和其中可能存在的内部异常。

“这会导致所有线程停止”。不应该。你确定你没有终止应用程序或类似的事情吗?你有没有在线程上调用Abort的代码?如果不是的话,那么我会说没有线程会以这种问题终止。而且,“不使用锁”不足以判断这是否会导致问题。如果共享的数据结构不是线程安全的,可能会导致线程抛出异常,但不会导致线程“中止”。当线程被中止时,这是因为使用thread对象上的abort方法显式要求线程中止。如果线程抛出异常,它将终止,但不会“中止”。您使用的是ASP.NET吗?如果是这样:我怀疑您的示例代码是否真的重新创建了问题。如果一个线程杀死了应用程序的其余部分,那么这就不同于一个线程杀死了其他线程,但应用程序仍在运行。@MatthewWatson我认为这不适用于辅助线程。然而,我可能错了。这可能是因为它们在所有线程上连接,并且主线程由于这样的响应而中止。重定向,但是主线程无论如何不能在连接调用中,因为运行重定向的线程将被中止,因此它不能同时在连接调用中。“这将导致所有线程停止”。不应该。你确定你没有终止应用程序或类似的事情吗?你有没有在线程上调用Abort的代码?如果不是的话,那么我会说没有线程会以这种问题终止。而且,“不使用锁”不足以判断这是否会导致问题。如果共享的数据结构不是线程安全的,可能会导致线程抛出异常,但不会导致线程“中止”。当线程被中止时,这是因为使用thread对象上的abort方法显式要求线程中止。如果线程抛出异常,它将终止,但不会“中止”。您使用的是ASP.NET吗?如果是这样:我怀疑您的示例代码是否真的重新创建了问题。如果一个线程杀死了应用程序的其余部分,那么这就不同于一个线程杀死了其他线程,但应用程序仍在运行。@MatthewWatson我认为这不适用于辅助线程。然而,我可能错了。这可能是因为它们在所有线程上连接,而主线程由于这样的响应而被中止。重定向,但是主线程无论如何都不能在连接调用中,因为运行重定向的线程将被中止,因此它不能同时在连接调用中。实际上,中止具有适当try/catch/using块来处理一次性项目的线程实际上会在异常进一步冒泡之前运行Dispose。不过,不调用中止的建议是正确的,它是一个用于框架的低级方法,而不是用于用户代码。*它将调用dispose,因为在ThreadAbortException的帮助下,中止作为异常处理。*thread.abort还有其他副作用。正在编辑。@TomTom,谢谢你宝贵的回答。但我猜我们的应用程序重新启动,这导致线程中止。我们可以看看为什么应用程序会随机重启吗。因为它只是偶尔发生,而不是经常发生。某些未修改的异常可能会导致应用程序停止,特别是在IIS下-但它应该在事件日志中保留日志项。添加插装-我们将所有activieis转储到MS Azure Application Insights。实际上,中止具有正确tr的线程