如何处理BackgroundWorker线程中的exception?

在WPF应用程序中,我有一个有计算机的数据库访问任务,由计时器定期运行,此任务已在BackgroundWorker线程中执行。

当连接尝试失败时,我通过try_catch构造引发exception,我想更新UI线程中的状态栏文本。

BackgroundWorker是否有一些prebuild事件构造用于实现它,比如DoWorkEventHandlerRunWorkerCompletedEventHandler ,可以用于此吗? 如果没有,怎么做得更好?

编辑(补充):

如果我想在RunWorkerCompletedEventHandler处理exception,使用e.Error参数,它不起作用。 如果我在BackgroundWorker线程中保留未处理的exception,则应用程序挂起并且调试器指向在BackgroundWorker线程内部执行的代码字符串,并说: 用户代码未处理exception

因此,在这种情况下,线程不会停止,向RunWorkerCompletedEventHandler发出信号,表示它因错误而停止,但整个应用程序停止工作。

可以使用Dispatcher.BeginInvoke从后台线程更新WPF UI。

例如,如果您的后台代码是Window的一部分,那么您可以更新TextBlock:

 this.Dispatcher.BeginInvoke((Action)(() => { textBlock.Text = "Connection Failed!"; })); 

编辑:

如果您的后台代码位于Window以外的类中,您可以创建一个界面来帮助:

 public interface IShowStatus { void ShowStatus(string message); } 

在Window中实现接口

 public void ShowStatus(string message) { this.Dispatcher.BeginInvoke((Action)(() => { textBlock.Text = message; })); } 

在您的类中,后台工作者创建一个属性来保存对接口的引用。

 public IShowStatus StatusDisplay { get; set; } 

在Window类中初始化背景类。

 public void InitBackground() { BackgroundClass background = new BackgroundClass(); background.StatusDisplay = this; ... 

最后在你的后台主题中你可以说:

 StatusDisplay.ShowStatus("Connection Failed!"); 

RunWorkerCompletedEventArgs eRunWorkerCompletedEventHandler包含属性Error它的类型为Exception。 如果在后台线程的工作期间没有发生exception,则prpery的值为null。 否则它包含发生的错误。

 private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { Exception exceptionThrowDuringDoWorkEventHandler = e.Error; } 

将后台worker的WorkerReportsProgress属性设置为true ,然后为事件ProgressChanged添加事件处理程序。 在下面的代码中,我还为Form.Load添加了一个事件处理程序。

现在尝试以下代码:

 private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { MessageBox.Show(e.UserState.ToString()); } private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { try { //some code that throws an exception throw new NotImplementedException(); } catch (Exception ex) { backgroundWorker1.ReportProgress(0/*percent of progress*/, ex); } } private void Form1_Load(object sender, EventArgs e) { backgroundWorker1.RunWorkerAsync(); } 

如果我想在RunWorkerCompletedEventHandler处理exception,使用e.Error参数,它不起作用。 如果我在BackgroundWorker线程中保留未处理的exception,则应用程序挂起并且调试器指向在BackgroundWorker线程内部执行的代码字符串,并说: 用户代码未处理exception

因此,在这种情况下,线程不会停止,向RunWorkerCompletedEventHandler发出信号,表示它因错误而停止,但整个应用程序停止工作。

我对此非常好奇。 尝试在控制台应用程序中运行以下代码,看看程序是否崩溃或者错误是否显示在RunWorkerCompletedEventArgs

  static void Main(string[] args) { var bw = new BackgroundWorker(); bw.DoWork += Bw_DoWork; bw.RunWorkerCompleted += Bw_RunWorkerCompleted; bw.RunWorkerAsync(); Console.ReadKey(); } private static void Bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { Console.WriteLine("Complete."); Console.WriteLine(e.Error); } private static void Bw_DoWork(object sender, DoWorkEventArgs e) { throw new NotImplementedException(); }