【问题标题】:How to tell if a ThreadPool thread died silently如何判断 ThreadPool 线程是否静默死亡
【发布时间】:2014-03-05 00:15:11
【问题描述】:

我现在正处于 DLL 地狱中,试图让我的代码在不同应用程序的框架内工作。在很长一段时间里,我一直在苦苦思索,试图理解为什么我的方法显然被排入 ThreadPool 时没有被调用。

最终证明,一个特定的 DLL 必须与调用方法位于同一文件夹中,或者找不到它,ThreadPool 线程要么死掉,要么默默地放弃工作(就像忍者一样)。

显然,该解决方案编译得非常完美,并且没有任何错误,因为正在构建有问题的 DLL,只是到另一个文件夹。这不是第一次 ThreadPool 线程因为放错位置的 DLL 而在我身上默默地死掉了。

  1. 我的线程消失后到底发生了什么?
  2. 我如何确定将来会发生这种情况?有没有机会在某个地方有一个日志文件?

一些代码:

protected void Enqueue()
{
    try
    {
        Task.Run(() => Process());
    }
    catch (Exception ex)
    {
        // Logging code here (no issues)
    }
}

protected void Process()
{
    // A breakpoint here will never be called

    try {       
        // Code that calls into offensive DLL
    }
    catch (Exception e)
    {
        // Logging code
    }
}

【问题讨论】:

  • 您是否尝试过在工作线程入口函数周围放置 try/catch,并记录错误以查看可能正在杀死您的线程的未处理异常?
  • @LB2 不应该取消这个过程吗?
  • 线程应该很少只是“消失”。他们可以,但这通常意味着整个应用程序都会消失。 +1 订阅 ThreadException 事件。此外,将线程条目的主体包装在 try/catch 中并输出发生的任何异常。一旦你这样做了,你可以发回你得到的任何异常,有人可以给你更具体的建议。
  • Application.ThreadException 是个坏建议,它只会触发 UI 线程上引发的异常,并且本身会产生大量噪音。损坏的日志记录是这里明显的故障模式。

标签: c# threadpool


【解决方案1】:

假设 Process 包含对 DLL 的调用。如果是这样,则在进程的 JIT 上抛出异常,因此您无法在 Process 中捕获它。在调用 DLL 之前使用更多的间接层以确保能够记录它。

protected void Enqueue()
{
    try
    {
        Task.Run(() => Process());
    }
    catch (Exception ex)
    {
        // Logging code here (no issues)
    }
}

protected void Process()
{
    try {
        Process2();
    }
    catch (Exception e)
    {
        // Logging code
    }
}

protected void Process2()
{
            // Code that calls into offensive DLL
}

【讨论】:

  • 谢谢!让我感到困惑的是,这个 DLL 中包含的静态方法不仅可以编译,甚至可以工作,而实例方法则抛出 MissingMethodExceptions。我不认为 JIT 编译器对两者进行了区分。
  • 如果你得到的是 MissingMethod 而不是没有找到,那么你在某个地方(比如 PATH)获取了另一个版本的 DLL。
猜你喜欢
  • 2016-03-19
  • 1970-01-01
  • 2011-02-16
  • 1970-01-01
  • 2018-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多