あなたの名前に基づいて、私はあなたが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;
}
}
例:結果を介してデータを返す
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();
}
}