多线程异常处理

3
这是一个简单的程序:
class Program
{
    static Calc calc = new Calc();

    static void Main(string[] args)
    {
        try
        {
            var t1 = new Thread(calc.Divide);
            t1.Start();
        }
        catch (DivideByZeroException e)
        {
            //Console.WriteLine("Error thread: " + e.Message);
        }

        try
        {
            calc.Divide();
        }
        catch (Exception e)
        {
            //Console.WriteLine("Error calc: " + e.Message);
        }

    }

    class Calc
    {
        public int Num1;
        public int Num2;

        Random random = new Random();

        public void Divide()
        {
            for (int i = 0; i < 100000; i++)
            {
                Num1 = random.Next(1, 10);
                Num2 = random.Next(1, 10);

                try
                {
                    int result = Num1 / Num2;
                }
                catch (Exception ex)
                {
                    throw ex;
                }

                Num1 = 0;
                Num2 = 0;
            }
        }
    }
}

两个线程同时执行同一方法。其中一个将Num1设置为0,而另一个则尝试同时除以Num1(0)。问题是为什么会引发异常,为什么它没有被Main方法内的try catch块捕获?

enter image description here


3
异常不会从一个线程冒泡到启动它的线程。甚至无法保证启动抛出异常的线程仍然存在。 - vcsjones
另外,请注意,IDE有时(取决于设置)会在异常发生时停止,即使它被捕获了(并不是在这种情况下第一个catch捕获)。 - George Duckett
"throw ex;"总是一个不好的模式 - H H
TPL的一个(重要)特性是捕获并将异常传递给调用者。裸线程无法做到这一点。 - H H
1个回答

0

主线程是一个线程,而您的新线程是另一个线程。这两个线程不会相互通信,意味着它们是完全独立的。如果您想在主线程上捕获异常,有两种方法可以做到:

  1. 使用BackgroundWorker类,RunWorkerCompleted事件将在主线程上触发,e.exception将告诉您是否有异常导致线程中止。

  2. 使用全局异常处理器

在您的代码之前添加此行

Application.Current.DispatcherUnhandledException += Current_DispatcherUnhandledException;

void Current_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
//handle the exception
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接