后台工作人员正在运行但不打印任何内容

时间:2016-01-07 12:29:20

标签: c# winforms backgroundworker

我有一个名为BackgroundWorker的{​​{1}},我将自定义的bgw Form传递给了LogBoxForm。自定义Form作业只是在其上打印一些内容。

LogBoxForm logBox = new LogBoxForm(); //both declared in the main Form
BackgroundWorker bgw = new BackgroundWorker();

在主Form Load event发起了两个bgw事件:DoWorkRunWorkerCompleted,就像这样< / p>

bgw.DoWork += bgw_DoWork;
bgw.RunWorkerCompleted += bgw_RunWorkerCompleted;

然后,当我按下名为Button的{​​{1}}时,button9将按照此代码的指示运行

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()); } 行停止这是我收到的错误消息:

  

System.InvalidOperationException:跨线程操作无效:   Control&#39; richTextBoxAll&#39;从线程以外的线程访问   它创建于。

我是catch的新用户,可能并不真正意识到所有这些都会发生。我希望一些更有经验的人可以告诉我的代码有什么问题。我期待着你的指导。

1 个答案:

答案 0 :(得分:4)

这应该是Thread Affinity的经典案例。由于BackgroundWorker运行在除UI线程之外的其他线程上,因此您需要调用.Invoke。查看此链接here以查看封装线程安全调用的扩展方法示例。

使用此扩展方法,您可以编写WinForms线程安全代码,如下所示:

this.ThreadSafeInvoke(() => logBox.WriteTimedLogLine("loop " + (i + 1).ToString()));

这里的关键是,由于您在另一个线程上执行,.InvokeRequired bool将返回true,然后您将通过{{执行Action传递到ThreadSafeInvoke 1}} - 它将封送回UI线程。

如果您不想使用扩展方法,只需执行以下操作:

.Invoke

扩展方法的优点是显而易见的。我希望你觉得这很有帮助。