I understand that blocking on async code is disapproved in most cases.
However, I have a WPF application executing a background task. When the user closes the window, this task should be canceled and the closing of the window delayed until cancellation and subsequent cleanup has been completed. In the meantime, any further user input should be blocked.
After a bit of searching & trying, I came up with the following code:
ViewModel.cs:
async void RunTaskAsync()
{
_cancelTknSource = new CancellationTokenSource();
try {
await Task.Run(/*...long running calculation...*/, _cancelTknSource.Token);
}
catch (OperationCanceledException) { }
finally {
/*...cleanup...*/
_cancelTknSource.Dispose();
_cancelTknSource = null;
}
}
async Task CancelAsync()
{
_cancelTknSource?.Cancel();
while (_cancelTknSource != null) {
Thread.Sleep(10);
await Task.Yield(); //prevents dead-lock
}
}
Window.xaml.cs:
async void Window_Closing(object sender, CancelEventArgs e)
{
e.Cancel = true;
await DataContext.CancelAsync();
Close();
}
(All these methods are called from the UI thread)
Is this good practice? If not, what are the alternatives?