【问题标题】:Multithreading | Thread was being aborted多线程 |威胁已经被清除了
【发布时间】:2020-02-28 11:14:12
【问题描述】:

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

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();

我们正在调用rest api,写入文件并更新RunLongRunningJob中的数据库记录。

附:我们没有使用LOCKS,这可能是原因吗?

【问题讨论】:

  • “导致所有线程停止”。它不应该。你确定你没有终止应用程序或类似的东西吗?您是否有任何代码在线程上调用 Abort?如果不是,那么我会说根本不应该有任何线程因这种问题而终止。
  • 另外,“不使用锁”也不足以判断这是否会导致问题。如果您共享的数据结构不是线程安全的,它可能会导致线程抛出异常,但不会导致线程“被中止”。当线程被中止时,这是因为使用线程对象上的 Abort 方法明确要求线程中止。如果线程抛出异常,它将终止,但不会“中止”。
  • 您使用的是 ASP.NET 吗?如果是这样:stackoverflow.com/questions/7629986/…
  • 我怀疑您的示例代码实际上是重现问题。如果一个线程杀死了应用程序的其余部分,那么这与一个线程杀死其他线程但应用程序仍然运行不同。
  • @MatthewWatson 我认为这不适用于辅助线程。然而,我可能是错的。可能是它们加入了所有线程,并且由于这样的 Response.Redirect 主线程被中止,但是主线程无论如何都不能在 Join 调用中,因为运行重定向的线程将被中止,因此它不能同时处于加入呼叫中。

标签: c# multithreading thread-safety


【解决方案1】:

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

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

http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation

这是关于时间安排和线程在非常糟糕的情况下最终没有正确执行的问题。

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

【讨论】:

  • 实际上,中止具有适当 try/catch/using 块来处理一次性项目的线程实际上会在异常进一步冒泡之前运行 Dispose。不过,不调用 Abort 的建议是正确的,它是一种用于框架的低级方法,而不是用于用户代码。
  • * 它将调用 dispose 因为在 ThreadAbortException 的帮助下将中止作为异常处理。 * thread.abort 还有其他副作用。编辑。
  • @TomTom,感谢您的宝贵回答。但我猜我们的应用程序重新启动导致线程中止。有什么我们可以看看为什么应用程序随机重启的原因。因为它只是有时不定期发生。
  • 记录。某些未处理的异常可能会导致应用程序停止,尤其是在 IIS 下 - 但它应该在事件日志中留下一个日志条目。添加检测 - 我们将所有活动转储到 MS Azure Application Insights。
猜你喜欢
  • 2010-11-28
  • 1970-01-01
  • 1970-01-01
  • 2011-09-12
  • 1970-01-01
  • 2015-09-04
  • 2015-09-22
  • 1970-01-01
相关资源
最近更新 更多