使用BackgroundWorker时未捕获异常

时间:2012-12-08 21:46:59

标签: c# .net exception-handling

我有一个BackgroundWorker的WPF窗口。我在Send()方法中遇到异常:

private void worker_DoWork(object sender, DoWorkEventArgs e)
{
     smtpClient.Send(mail);
}

反过来在Click事件中调用某个按钮,如下所示:

private async void SendClickAsync(object sender, RoutedEventArgs e)
{
    using (MessageServiceClient client = new MessageServiceClient())
    {
        try
        {
            [...]
            worker.RunWorkerAsync();

        }
        catch (Exception ex)
        {
            MessageBox.Show("Error! Check your sender data!", "!", MessageBoxButton.OK, MessageBoxImage.Error);
            [...]
        }
    }
}

为什么不处理此异常?当我不是异步地(一切都在SendClickAsync()方法中)时,消息框弹出很好。

3 个答案:

答案 0 :(得分:11)

当您调用worker.RunWorkerAsync()方法时,主线程继续执行并退出try..catch块。处理异常使用RunWorkerCompleted事件处理程序。 RunWorkerCompletedEventArgs争论的属性Error将包含异常对象:

void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Error != null)
    {
       MessageBox.Show("Error", "!", MessageBoxButton.OK, MessageBoxImage.Error);
       return;
    }
}

答案 1 :(得分:3)

BackgroundWorker正在使用线程池线程,因此它不希望您的代码能够在工作线程上做一些奇怪的事情。这就是BackgroundWorker吞下DoWork期间发生的异常并让您知道它是通过RunWorkerCompletedEventArgs.Error发生的原因。

答案 2 :(得分:2)

未处理异常的原因是因为它被抛出在不同的线程上。 对worker.RunWorkerAsync();的调用不会阻塞,而是在线程池上启动作业并立即在主线程中返回控制 - 这是异步执行它的重点。

但这也意味着在调用worker.RunWorkerAsync()之后主线程退出了try-catch块,因此异常不会被处理(在主线程上)。