如果在辅助线程中发生异常,如何在主线程中捕获异常?

时间:2010-06-01 05:15:12

标签: c# .net multithreading

如果在辅助线程中发生异常,如何在主线程中捕获异常?

该方案的代码段如下:

private void button1_Click(object sender, EventArgs e)
{
    try
    {
        Thread th1 = new Thread(new ThreadStart(Test));
        th1.Start();               
    }
    catch (Exception)
    { 

    }
}

void Test()
{
    for (int i = 0; i < 100; i++)
    {
        Thread.Sleep(100);

        if (i == 2)
            throw new MyException();
    }
}

6 个答案:

答案 0 :(得分:3)

您可以添加Application.ThreadException事件处理程序:

乔是对的。鉴于上面的Windows窗体代码我假设Windows窗体:

  

此事件允许您的Windows窗体   申请处理否则   未处理的异常发生在   Windows窗体线程。附上你的   ThreadException的事件处理程序   处理这些例外的事件,   这将留下你的申请   一个未知的状态。在可能的情况,   例外应由a处理   结构化异常处理块。

请参阅Unexpected Errors in Managed Applications

答案 1 :(得分:2)

使用BackgroundWorker

BackgroundWorker提供了用于在主UI线程和后台工作线程之间进行通信的基础结构,包括报告异常。它几乎总是比从button_click事件处理程序启动线程更好的解决方案。

答案 2 :(得分:1)

您应该考虑在测试方法中添加异常处理并处理异常处理。

免费的Threading in C#电子书讨论了这种方法(以及其他一些方法)。向下滚动到“异常处理”部分。

答案 3 :(得分:0)

如果您担心全局捕获所有异常,您也可以使用异步委托来冒泡信息。

请参阅here

也就是说,在线程B中捕获异常,并使用Async Delegate将信息冒泡到线程A.这种方式可以专门针对处理异常数据的目标。

答案 4 :(得分:0)

正如@codeka所说,你做不到。但是如果你想在辅助线程的catch块中做一些UI东西(可能会向用户显示错误MessageBox),你可以这样包围。如果您使用BackgroundWorker

,效果会更好
Invoke(new Action(() =>
{
  MessageBox.Show("Message");
}));

答案 5 :(得分:0)

您可以(现在......在最初询问问题时无效)使用asyncawait

private async void button1_Click(object sender, EventArgs e)
{
    try
    {
        await Task.Run(Test);
    }
    catch (Exception)
    { 

    }
}

Task.Run()方法将导致Test()方法在工作线程中执行。如果在该线程中抛出了未处理的异常,Task会将该异常传播回await语句中的等待线程。