我有一个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()
方法中)时,消息框弹出很好。
答案 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块,因此异常不会被处理(在主线程上)。