【问题标题】:Why does Win32Exception thrown in .NET thread pool cause application hang under a debugger?为什么在 .NET 线程池中抛出 Win32Exception 会导致应用程序在调试器下挂起?
【发布时间】:2013-12-06 11:49:55
【问题描述】:

这是我的简单 C# 控制台应用程序:

using System.Diagnostics;
using System.Threading;

public static class Program
{
    public static int Main(string[] args)
    {
        var e = new AutoResetEvent(false);
        ThreadPool.QueueUserWorkItem(state =>
        {
            Process.Start("nonexistent path");
            e.Set();
        });
        e.WaitOne();
        return 0;
    }
}

如果我在调试器中运行这个程序,它会在关机时挂起。如果我用throw new System.Exception(); 替换Process.Start("nonexistent path"); 行(抛出System.ComponentModel.Win32Exception,它不会挂起并且程序按预期终止。

在我看来,.NET/CLR 或调试器必须以某种特殊方式处理 Win32Exception。这是预期的行为吗?

这是在 .NET/CLR 4.0 上运行的,其中工作线程上未处理的异常应该终止应用程序:CLR 2.0 及更高版本 (http://msdn.microsoft.com/en-us/library/ms228965.aspx) 就是这种情况。

更新

到目前为止,当从 Cygwin 终端启动程序时,我只能在 32 位 Windows 操作系统上重现此问题。

【问题讨论】:

  • 很奇怪。我刚刚复制了你的代码,代码正常结束
  • 您确实从 sn-p 中删除了太多代码,并添加了许多猴子尾巴以混淆真正的问题。 This question 是匹配项。
  • 我删除了@。然而,这是一个功能齐全的代码 sn-p。

标签: c# .net windows clr


【解决方案1】:

还有另一个问题:ManualResetEvent 创建时未设置。因为后台线程在设置 ManualResetEvent 之前就失败了,所以主线程卡在了@event.WaitOne() 语句上。

【讨论】:

  • 我认为情况并非如此。在工作线程上抛出未处理的异常应该会导致整个进程终止。
  • 我不知道 ThreadPool.QueueUserWorkItem 方法如何处理异常(并且它也没有记录在 MSDN 的相应页面中)。无论如何,当使用 Tasks 时,异常会被 TPL 捕获并等待一些继续任务将其抛出。如果没有此类任务到达,则异常将在 Task 对象的终结器上抛出 - 经过长时间的延迟(甚至可能是几分钟) .也许这里的情况类似于使用任务时发生的情况。您可以尝试在设置事件后抛出异常以检查此理论。
猜你喜欢
  • 2015-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多