在WPF应用程序中,我有一个有计算机的数据库访问任务,定期由计时器运行,此任务已在BackgroundWorker线程中执行。
当连接尝试失败时,我通过try_catch
构造引发异常,我想更新UI线程中的状态栏文本。
BackgroundWorker
中是否有一些prebuild事件构建用于实现此功能,例如DoWorkEventHandler
或RunWorkerCompletedEventHandler
,可用于此目的吗?如果没有,怎么做得更好?
已编辑(已添加):
如果我想使用RunWorkerCompletedEventHandler
参数处理e.Error
内的异常,则它不起作用。如果我在BackgroundWorker
线程中未处理异常,应用程序挂起并且调试器指向在BackgroundWorker
线程内部执行的代码字符串,说: 异常未被处理用户代码 。
因此,在这种情况下,线程不会停止,向RunWorkerCompletedEventHandler
发信号通知它因错误而停止,但整个应用程序停止工作。
答案 0 :(得分:6)
RunWorkerCompletedEventArgs e
的{{1}}包含属性RunWorkerCompletedEventHandler
,它的类型为Exception。如果在后台线程的工作期间没有发生异常,则prpery为null。否则它包含发生的错误。
答案 1 :(得分:5)
可以使用Dispatcher.BeginInvoke从后台线程更新WPF UI。
例如,如果您的后台代码是Window的一部分,那么您可以更新TextBlock:
this.Dispatcher.BeginInvoke((Action)(() =>
{
textBlock.Text = "Connection Failed!";
}));
编辑:
如果您的后台代码位于Window以外的类中,您可以创建一个界面来提供帮助:
public interface IShowStatus
{
void ShowStatus(string message);
}
在您的窗口中实现界面
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!");
答案 2 :(得分:3)
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Exception exceptionThrowDuringDoWorkEventHandler = e.Error;
}
答案 3 :(得分:3)
将后台工作程序的 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();
}
答案 4 :(得分:0)
如果我想在里面处理异常
RunWorkerCompletedEventHandler
,使用e.Error
参数 不起作用。如果我把未处理的异常留在了BackgroundWorker
线程,应用程序挂起,调试器指向 在BackgroundWorker
线程内部执行的代码字符串, 说: 用户代码无法处理异常 。因此,在这种情况下,线程不会停止,发信号通知
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();
}