尝试/捕捉和线程

Otá*_*cio 13 c# multithreading try-catch

我知道为什么,但我想问一下是否有人很清楚为什么在一个线程中引发的异常永远不会被启动它的代码捕获.这是一些非常简单的代码来演示我的意思:

using System;
using System.Collections.Generic;
using System.Threading;

namespace TestCrash
{
    class Program
    {
        private static void Crash(object control)
        {
            AutoResetEvent are = (AutoResetEvent)(((object[])control)[0]);
            are.Set();
            throw new Exception("Burn baby burn");
        }
        static void Main(string[] args)
        {
            try
            {
                List<WaitHandle> waitHandles = new List<WaitHandle>();
                for (int i = 0; i < 100; i++)
                {
                    AutoResetEvent are = new AutoResetEvent(false);
                    waitHandles.Add(are);
                    object[] procControl = new object[] { are };
                    ThreadPool.QueueUserWorkItem(Crash, procControl);
                    WaitHandle.WaitAll(waitHandles.ToArray());
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我天真地认为通过try/catch我会安全,但我发现事实并非如此(它崩溃了我的一项服务).

Jon*_*eet 28

总的来说,在新线程中抛出异常时,你不知道原始线程在哪里 - 为什么它会等待线程抛出异常?

想想所涉及的堆栈 - 当抛出异常时,它会上升到堆栈,直到到达适当的catch块.新线程与创建线程具有完全独立的堆栈,因此它永远不会到达创建线程堆栈中的catch块.

编辑:当然,您可以设计您的系统,以便创建线程确实等待其他事情发生 - 有点像Windows窗体应用程序中的消息循环.然后,新线程可以捕获异常并向创建线程发送消息,然后可以处理异常.这不是正常的设置 - 您必须明确地完成所有操作.


Kib*_*bee 5

正在运行的线程不会被您的 try/catch 语句捕获,因为它正在另一个线程中运行。Try/Catch 只适用于当前线程。您需要做的是在线程运行的函数中使用 try/catch,并采用某种方法来管理崩溃发生时发生的情况。