c#后台工作者:当Close()被调用时异常
本文关键字:调用 异常 Close 后台 工作者 | 更新日期: 2023-09-27 18:09:31
我的应用程序中有两个后台工作者,它们填充一个表并发送日志消息。它们使用ReportProgress方法的"userState"传输这些数据。
它们通过:
msg_worker.DoWork += message_worker_task;
msg_worker.ProgressChanged += msg_worker_ProgressChanged;
msg_worker.RunWorkerCompleted += worker_completed;
data_worker.DoWork += data_worker_task;
data_worker.ProgressChanged += data_worker_ProgressChanged;
data_worker.RunWorkerCompleted += worker_completed;
它们使用在doWork任务结束时设置的两个EventWaitHandle项进行同步:
private void message_worker_task(object sender, DoWorkEventArgs e)
{
try
{
while( .. ){
// do work
bw.ReportProgress( 10, new String("my message to append"));
}
}
finally
{
e.Result = 0;
msg_done.Set(); // EventWaitHandle
}
}
Progress更改了在用户可见的组件中插入数据/日志的委托。
现在,问题是,当我点击退出按钮在我的UI,我等待这两个线程:
private void wait_threads()
{
int timeout = 30000;
Cursor.Current = Cursors.WaitCursor;
if (data_worker.IsBusy && !data_worker.CancellationPending)
{
data_worker.CancelAsync();
data_done.WaitOne(timeout);
}
if (msg_worker.IsBusy && !msg_worker.CancellationPending)
{
msg_worker.CancelAsync();
msg_done.WaitOne(timeout);
}
Cursor.Current = Cursors.Default;
}
这似乎是工作(我在代码的其他地方使用它),但在这种"退出"的情况下,我有一个异常,说我试图插入数据到日志组件我有。这个组件是由RunWorkerCompleted委托操作的。
点击Quit时执行的代码是这样的:
private void quit_Click(object sender, EventArgs e)
{
wait_threads(); // blocks until threads are finished
Close();
}
我想我弄清楚了,在等待线程完成时,他们发送最后一个事件:RunWorkerCompleted。问题是我在Close()的过程中我的形式,这意味着形式不是在一个正确的状态。更重要的是,如果我检查worker_completed
函数中的e.Cancelled
标志,我认为它为假…
我能做些什么来确保RunWorkerCompleted被处理之前我的Close()
函数得到执行?(更确切地说,根本不处理,因为我们正在退出)。
我想你可以在调用ReportProgress之前检查cancel Pending属性。
while( .. ){
if (!bw.CancellationPending)
bw.ReportProgress( 10, new String("my message to append"));
}