后台工作程序正在运行,但没有;t打印任何内容

本文关键字:打印 任何内 工作程序 运行 后台 | 更新日期: 2023-09-27 18:29:31

我有一个名为bgwBackgroundWorker,我将名为LogBoxForm的自定义Form传递给它。自定义Form作业只是在上面打印一些东西。

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

在主FormLoad中,event启动了两个bgw事件:DoWorkRunWorkerCompleted,就像这个一样

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

然后,当我按下一个名为button9Button时,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的新用户,可能真的不知道这些是怎么发生的。我希望一些更有经验的人能告诉我的代码出了什么问题。我期待着你的指导。

后台工作程序正在运行,但没有;t打印任何内容

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

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

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

这里的关键是,由于您在不同的线程上执行,.InvokeRequired布尔将返回true,然后您将执行通过.Invoke传递到ThreadSafeInvokeAction,这将封送回UI线程。

如果你不想有一个扩展方法,只需执行以下操作:

this.Invoke(new MethodInvoker(() => 
                logBox.WriteTimedLogLine("loop " + (i + 1).ToString())));

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