I have a Windows form which opens another form. In the secondary form it starts a Task asynchronously. If the user starts the task and then cancels it and quickly closes the form, the form is Disposed and set to null however when the task comes back from being cancelled I still get a MessageBox.Show happen
public class MyMainForm : Form
{
public void OpenChildForm()
{
MyChildForm form = new MyChildForm();
form.ShowDialog();
form.Dispose();
form = null;
}
}
public class MyChildForm : Form
{
private CancellationTokenSource MyTokensource;
private Task task;
public void StartTask()
{
MyTokensource = new CancellationTokenSource();
task = Task.Factory.StartNew(() => MyMethod(MyTokensource.Token), MyTokensource.Token);
}
public void MyMethod(CancellationToken token)
{
var result = StaticClass.DoSomethingLengthy(token); //The cancel make take a couple of seconds to return here
if (result == Cancelled)
{
MessageBox.Show("Cancelled");
UpdateLabel("Cancelled")
}
}
public void ButtonClose_Click()
{
if (task != null && !task.IsCompleted)
{
MyTokensource.Cancel();
}
this.Close();
}
}
Setting the variable that is a reference to the form to null, and even calling Dispose() on the form, does not actually destroy the form. The Task is still executing until it’s cancelled (
CancellationTokenSourceis designed as a cooperative model for cancellation).As such, you need to explicitly handle the code path that occurs when the task is cancelled. This may be as simple as checking to see if you’re disposed already, ie: