I would use a Task for this, as it has built in mechanisms to handle errors, cancellation, and running Continuation Tasks when the task completes.
Assuming a custom return type of Move which I think you implied in your question:
private Task<Move> _searchTask;
private CancellationTokenSource _searchCancellationTokenSrc;
Then on a button click or similar, kick off your task. This will return immediately, keeping your UI responsive:
private void StartButton_Click(object sender, RoutedEventArgs e)
{
_searchCancellationTokenSrc = new CancellationTokenSource();
CancellationToken ct = _searchCancellationTokenSrc.Token;
_searchTask = Task.Run(() =>
{
for (int i = 0; i < 10; i++ )
{
if(ct.IsCancellationRequested)
{
// Clean up here
ct.ThrowIfCancellationRequested();
}
// Time consuming processing here
Thread.Sleep(1000);
}
return new Move();
},ct);
_searchTask.ContinueWith((t) =>
{
Console.WriteLine("Canceled");
}, TaskContinuationOptions.OnlyOnCanceled);
_searchTask.ContinueWith((t) =>
{
Console.WriteLine("Faulted. t.Exception contains details of any exceptions thrown");
}, TaskContinuationOptions.OnlyOnFaulted);
_searchTask.ContinueWith((t) =>
{
Console.WriteLine("Completed t.Result contains your Move object");
}, TaskContinuationOptions.OnlyOnRanToCompletion);
}
To cancel this, perhaps from another button:
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
_searchCancellationTokenSrc.Cancel();
}
backgroundworkerandTaskasync implementations support cancellation (though by different approaches, one bybooland other bytoken). I suggest usingTaskas it is a newer approach.