2012-12-08 50 views
1

我有一个带有BackgroundWorker的WPF窗口。我在这里Send()方法得到异常:使用BackgroundWorker时未捕获异常

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()方法)消息框很好地弹出。

回答

11

当你调用worker.RunWorkerAsync()方法时,你的主线程继续执行并退出try..catch块。处理异常使用RunWorkerCompleted事件处理程序。 RunWorkerCompletedEventArgs arguement拥有财产Error其中将包含异常对象:

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

+1,你快了:) – Vlad

3

BackgroundWorker使用线程池中的线程,所以它不希望你的代码能够做一些工作线程上的怪异。这就是为什么BackgroundWorker会吞噬您在DoWork期间发生的异常,并通过RunWorkerCompletedEventArgs.Error让您知道它发生了。

2

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

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