Invalid Cross-Thread Operations from BackgroundWorker2_RunWorkerCompleted in C#
Posted
by Jim Fell
on Stack Overflow
See other posts from Stack Overflow
or by Jim Fell
Published on 2010-05-12T15:59:49Z
Indexed on
2010/05/12
16:04 UTC
Read the original article
Hit count: 229
Hello. I'm getting an error that does not make sense.
Cross-thread operation not valid: Control 'buttonOpenFile' accessed from a thread other than the thread it was created on.
In my application, the UI thread fires off backgroundWorker1
, which when almost complete fires off backgroundWorker2
and waits for it to complete. backgroundWorker1
waits for backgroundWorker2
to complete, before it completes. AutoResetEvent
variables are used to flag when each of the workers complete. In backgroundWorker2_RunWorkerComplete
a function is called that resets the form controls. It is in this ResetFormControls()
function where the exception is thrown. I thought it was safe to modify form controls in the RunWorkerCompleted
function. Both background workers are instantiated from the UI thread. Here is a greatly summarized version of what I am doing:
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();
}
Any thoughts or suggestions you may have would be appreciated. I am using Microsoft Visual C# 2008 Express Edition. Thanks.
© Stack Overflow or respective owner