How to handle window closed in the middle of a long running operation gracefully?
- by Marek
We have the following method called directly from the UI thread:
void DoLengthyProcessing()
{
DoStuff();
var items = DoMoreStuff();
//do even more stuff - 200 lines of code trimmed
this.someControl.PrepareForBigThing(); //someControl is a big user control
//additional 100 lines of code that access this.someControl
this.someControl.Finish(items);
}
Many of the called methods call Application.DoEvents() (and they do so many times) (do not ask me why, this is black magic written by black magic programmers and it can not be changed because everyone is scared what the impact would be) and there is also an operation running on a background thread involved in the processing. As a result, the window is not fully nonresponsive and can be closed manually during the processing.
The Dispose method of the form "releases" the someControl variable by setting it to null.
As a result, in case the user closes the window during the lengthy process, a null reference exception is thrown.
How to handle this gracefully without just catching and logging the exception caused by disposal?
Assigning the someControl instance to a temporary variable in the beginning of the method - but the control contains many subcontrols with similar disposal scheme - sets them to null and this causes null reference exceptions in other place
put if (this.IsDisposed) return; calls before every access of the someControl variable. - making the already nasty long method even longer and unreadable.
in Closing event, just indicate that we should close and only hide the window. Dispose it at the end of the lengthy operation. This is not very viable because there are many other methods involved (think 20K LOC for a single control) that would need to handle this mechanism as well.
How to most effectively handle window disposal (by user action) in the middle of this kind of processing?