C# 捕获.NET线程中的异常

C# 捕获.NET线程中的异常,c#,.net,multithreading,C#,.net,Multithreading,您如何发现多线程应用程序中的线程中发生了异常?不断清理资源? 因为否则线程仍可以保留在内存中并运行 A.您有一个调用堆栈,您可以在线程内捕获它,并将线程id添加到日志中,我猜 如果以良好的方式包装线程,则可以向catch部分添加清理代码,并在需要时终止线程。如果您担心此类问题,则应将线程入口点包装在try/catch块中,并显式执行清理。任何超出线程入口点的异常都将导致应用程序关闭。您可以像捕获任何正常功能一样捕获线程内的异常。 如果线程的“work”函数称为DoWork,则执行以下操作: pr

您如何发现多线程应用程序中的
线程中发生了
异常
?不断清理资源?


因为否则线程仍可以保留在内存中并运行

A.您有一个调用堆栈,您可以在线程内捕获它,并将线程id添加到日志中,我猜


如果以良好的方式包装线程,则可以向catch部分添加清理代码,并在需要时终止线程。

如果您担心此类问题,则应将线程入口点包装在try/catch块中,并显式执行清理。任何超出线程入口点的异常都将导致应用程序关闭。

您可以像捕获任何正常功能一样捕获线程内的异常。 如果线程的“work”函数称为DoWork,则执行以下操作:

private void DoWork(...args...)
{
try
{
// Do my thread work here
}
catch (Exception ex)
{
}
}

正如Sean所说,您必须在thread方法中完成所有异常处理和清理,而不能在线程初始化中完成。例如:

public void Run()
{
    try
    {
        Thread thread1 = new Thread(ThreadEntry1);
        thread1.Start();

        Thread thread2 = new Thread(ThreadEntry2);
        thread2.Start();
    }
    catch (NotImplementedException)
    {
        // Neither are caught here
        Console.WriteLine("Caught you");
    }
}

private void ThreadEntry1()
{
    throw new NotImplementedException("Oops");
}

private void ThreadEntry2()
{
    throw new NotImplementedException("Oops2");
}
相反,这种方法更加独立,显然也有效:

public void Run()
{
    Thread thread1 = new Thread(ThreadEntry1);
    thread1.Start();
}

private void ThreadEntry1()
{
    try
    {
        throw new NotImplementedException("Oops");
    }
    catch (NotImplementedException)
    {
        Console.WriteLine("Ha! Caught you");
    }
}

如果你想知道线程是否失败了,那么你应该考虑一个数组,然后回传给你的调用方法。另一种更简单的方法是在线程的操作每次完成时简单地增加一个计数器:

Interlocked.Increment(ref _mycounter);

Eric Lippert最近发表了一篇关于工作线程中发生的异常的不良影响的文章。值得阅读和理解的是,异常是“异常的”,在工作线程中发生异常后,您唯一可以确定的是,您无法再确定应用程序的状态。

同意。我不认为这是一个问题-你开始一个线程,它进入你的方法。。。。那么,是什么阻止了您处理异常呢?您无法使用默认设置捕获.Net 3.5或更低版本中的ThreadAbortException,也无法使用默认设置捕获可能代表.Net 4.0中损坏状态的异常。因此,使用默认设置(不建议您也这样做)使用try-catch块无法捕获所有异常。除非您中止线程,否则不会引发ThreadAbortException-您也可以捕获异常,但不能在引发异常时吞掉它们automatically@ChrisS,你说得对+1,我用了吞咽的意思,这在政治上是不正确的。