Я получаю сообщение об ошибке, которое не имеет смысла.
Cross-thread operation not valid: Control 'buttonOpenFile' accessed from a thread other than the thread it was created on.
В моем приложении поток пользовательского интерфейса отключается backgroundWorker1
, который при почти полном завершении запуска backgroundWorker2
и ожидает его завершения.backgroundWorker1
ожидает завершения backgroundWorker2
до его завершения.AutoResetEvent
переменные используются для отметки, когда каждый из рабочих завершается.В backgroundWorker2_RunWorkerComplete
вызывается функция, которая сбрасывает элементы управления формы.Именно в этой функции ResetFormControls()
создается исключение.Я думал, что было безопасно изменять элементы управления формой в функции RunWorkerCompleted
.Оба фоновых рабочих создаются из потока пользовательского интерфейса.Вот кратко изложенная версия того, что я делаю:
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.Спасибо.