Based on your names I am assuming you are using a BackgroundWorker. You must either update your controls in ProgressChanged, RunWorkerCompleted, Control.Invoke or Control.BeginInvoke (You do not need to fire EndInvoke for Control's BeginInvoke).
My recommendation is throw a exception in your background worker (if you are not using code other than checking for 0, if not use the Result method.) and check the Error property of the parameter passed in to the RunWorkerCompleted event. From there you can spin up another background worker or stop. you will be running on the main thread so you can change your buttons without invoking.
Example: Enabling the buttons via BeginInvoke
With this example you can use your code as is just modify 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;
}
}
Example: Returning data via 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();
}
}
Example: Returning data via Exception + reusing event handlers.
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();
}
}