gpt4 book ai didi

c# - C# 中的 BackgroundWorker2_RunWorkerCompleted 的无效跨线程操作

转载 作者:行者123 更新时间:2023-12-02 15:04:43 28 4
gpt4 key购买 nike

我收到一个没有意义的错误。

跨线程操作无效:从创建该控件的线程以外的线程访问控制“buttonOpenFile”。

在我的应用程序中,UI 线程会触发 backgroundWorker1,当它几乎完成时,会触发 backgroundWorker2 并等待其完成。 backgroundWorker1 等待 backgroundWorker2 完成,然后再完成。 AutoResetEvent 变量用于标记每个工作人员何时完成。在 backgroundWorker2_RunWorkerComplete 中,调用一个函数来重置表单控件。正是在这个 ResetFormControls() 函数中引发了异常。我认为在 RunWorkerCompleted 函数中修改表单控件是安全的。两个后台工作线程都是从 UI 线程实例化的。这是我正在做的事情的一个高度总结的版本:

  AutoResetEvent evtProgrammingComplete_c = new AutoResetEvent(false);
AutoResetEvent evtResetComplete_c = new AutoResetEvent(false);

private void ResetFormControls()
{
toolStripProgressBar1.Enabled = false;
toolStripProgressBar1.RightToLeftLayout = false;
toolStripProgressBar1.Value = 0;

buttonInit.Enabled = true;
buttonOpenFile.Enabled = true; // Error occurs here.
buttonProgram.Enabled = true;
buttonAbort.Enabled = false;
buttonReset.Enabled = true;
checkBoxPeripheryModule.Enabled = true;
checkBoxVerbose.Enabled = true;
comboBoxComPort.Enabled = true;
groupBoxToolSettings.Enabled = true;
groupBoxNodeSettings.Enabled = true;
}

private void buttonProgram_Click(object sender, EventArgs e)
{
while (backgroundWorkerProgram.IsBusy)
backgroundWorkerProgram.CancelAsync();

backgroundWorkerProgram.RunWorkerAsync();
}

private void backgroundWorkerProgram_DoWork(object sender, DoWorkEventArgs e)
{
// Does a bunch of stuff...

if (tProgramStat_c == eProgramStat_t.DONE)
{
tProgramStat_c = eProgramStat_t.RESETTING;

while (backgroundWorkerReset.IsBusy)
backgroundWorkerReset.CancelAsync();

backgroundWorkerReset.RunWorkerAsync();
evtResetComplete_c.WaitOne(LONG_ACK_WAIT * 2);

if (tResetStat_c == eResetStat_t.COMPLETED)
tProgramStat_c = eProgramStat_t.DONE;
}
}

private void backgroundWorkerProgram_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Updates form to report complete. No problems here.

evtProgrammingComplete_c.Set();
backgroundWorkerProgram.Dispose();
}

private void backgroundWorkerReset_DoWork(object sender, DoWorkEventArgs e)
{
// Does a bunch of stuff...

if (tResetStat_c == eResetStat_t.COMPLETED)
if (tProgramStat_c == eProgramStat_t.RESETTING)
evtProgrammingComplete_c.WaitOne();
}

private void backgroundWorkerReset_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
CloseAllComms();
ResetFormControls();
evtResetComplete_c.Set();
backgroundWorkerReset.Dispose();
}

如果您有任何想法或建议,我们将不胜感激。我正在使用 Microsoft Visual C# 2008 Express Edition。谢谢。

最佳答案

RunWorkerCompleted 将在启动BackgroundWorker 的线程上执行。由于您正在链接BackgroundWorkers(从1开始2),因此2的RunWorkerCompleted在1的线程上执行,而不是在UI线程上执行。

您需要使用 Invoke 编码回 UI 线程或将 UI 更新移至 1 的 RunWorkerCompleted。

我的建议是在更新 UI 时始终检查 InvokeRequired,这样您就无需担心它来自哪个线程。

关于c# - C# 中的 BackgroundWorker2_RunWorkerCompleted 的无效跨线程操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2820554/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com