根据您的姓名,我假设您使用的是BackgroundWorker。您必须更新ProgressChanged、RunWorkerCompleted、Control.Invoke或Control.BeginInvoke中的控件(您不需要为 Control 的 BeginInvoke 触发 EndInvoke)。
我的建议是在后台工作人员中抛出异常(如果您没有使用除检查 0 以外的代码,如果不使用 Result 方法。)并检查传递给 RunWorkerCompleted 事件的参数的Error属性。从那里您可以启动另一个后台工作人员或停止。您将在主线程上运行,因此您无需调用即可更改按钮。
示例:通过 BeginInvoke 启用按钮
使用此示例,您可以按原样使用您的代码,只需修改 EnableAllButtons
private void EnableAllButtons()
{
//See if the main form needs invoke required, assuming the buttons are on the same thread as the form
if(this.InvokeRequired)
{
//Calls EnableAllButtons a seccond time but this time on the main thread.
//This does not block, it is "fire and forget"
this.BeginInvoke(new Action(EnableAllButtons));
}
else
{
btnProcessImages.Enabled = true;
btnBrowse.Enabled = true;
btnUpload.Enabled = true;
btnExit.Enabled = true;
ControlBox = true;
}
}
示例:通过 Result 返回数据
private void processWorker1_DoWork(object sender, DoWorkEventArgs e)
{
string code = DoLongWorkAndReturnCode();
e.Result = code;
}
private void processWorkers_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (code != 0)
{
MessageBox.Show("Error!");
EnableAllButtons(); // this is defined in the other thread and it's where i run into the error.
}
else
{
doAnotherLongProcessAndReturnCodesBackgroundWorker.RunWorkerAsync();
}
}
示例:通过异常返回数据 + 重用事件处理程序。
private void processWorker1_DoWork(object sender, DoWorkEventArgs e)
{
string code = DoLongWorkAndReturnCode();
if (code != 0)
{
thow new MyCustomExecption(code);
}
}
private void processWorker2_DoWork(object sender, DoWorkEventArgs e)
{
string code = DoAnotherLongProcessAndReturnCode();
if (code != 0)
{
thow new MyCustomExecption(code);
}
}
private void processWorkers_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if(e.Error != null)
{
string message;
//See if it was our error
if(e.Error.GetType() == typeOf(MyCustomExecption))
{
//Choose which error message to send
if(sender.Equals(processWorker2))
message = "Error2!";
else
message = "Error!";
}
else
{
//Handle other types of thrown exceptions other than the ones we sent
message = e.Error.ToString();
}
//no matter what, show a dialog box and enable all buttons.
MessageBox.Show(message);
EnableAllButtons();
}
else
{
//Worker completed successfully.
//If this was called from processWorker1 call processWorker2
//Here is the code that was returned from the function
if(sender.Equals(processWorker1))
processWorker2.RunWorkerAsync();
}
}