后台工作程序正在运行,但没有;t打印任何内容
本文关键字:打印 任何内 工作程序 运行 后台 | 更新日期: 2023-09-27 18:29:31
我有一个名为bgw
的BackgroundWorker
,我将名为LogBoxForm
的自定义Form
传递给它。自定义Form
作业只是在上面打印一些东西。
LogBoxForm logBox = new LogBoxForm(); //both declared in the main Form
BackgroundWorker bgw = new BackgroundWorker();
在主Form
的Load
中,event
启动了两个bgw
事件:DoWork
和RunWorkerCompleted
,就像这个一样
bgw.DoWork += bgw_DoWork;
bgw.RunWorkerCompleted += bgw_RunWorkerCompleted;
然后,当我按下一个名为button9
的Button
时,bgw
将按照这个代码的指示运行
//Background worker
BackgroundWorker bgw = new BackgroundWorker();
private void button9_Click(object sender, EventArgs e) {
if (bgw.IsBusy)
return;
bgw.RunWorkerAsync(logBox);
}
void bgw_DoWork(object sender, DoWorkEventArgs e) {
LogBoxForm lbf = e.Argument as LogBoxForm;
try {
for (int i = 0; i < 5; ++i) {
lbf.WriteTimedLogLine("loop " + (i + 1).ToString());
Thread.Sleep(1000);
}
} catch (Exception exc) {
throw exc;
}
}
void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
logBox.WriteTimedLogLine("Completed!");
if (e.Error != null)
logBox.WriteTimedLogLine(e.Error.ToString());
}
它停在catch
行这是我得到的错误消息:
System.InvalidOperationException:跨线程操作无效:从线程以外的线程访问控件"richTextBoxAll"它是在上创建的。
我是BackgroundWorker
的新用户,可能真的不知道这些是怎么发生的。我希望一些更有经验的人能告诉我的代码出了什么问题。我期待着你的指导。
这应该是Thread Affinity的经典案例。由于BackgroundWorker
运行在UI线程之外的其他线程上,因此需要调用.Invoke
。请在此处查看此链接,以查看封装线程安全调用的扩展方法的示例。
使用此扩展方法,您可以编写WinForms线程安全代码,如下所示:
this.ThreadSafeInvoke(() => logBox.WriteTimedLogLine("loop " + (i + 1).ToString()));
这里的关键是,由于您在不同的线程上执行,.InvokeRequired
布尔将返回true,然后您将执行通过.Invoke
传递到ThreadSafeInvoke
的Action
,这将封送回UI线程。
如果你不想有一个扩展方法,只需执行以下操作:
this.Invoke(new MethodInvoker(() =>
logBox.WriteTimedLogLine("loop " + (i + 1).ToString())));
扩展方法的优点是显而易见的。我希望你觉得这很有帮助。