I am following a fairly common pattern for confirming/canceling my main window closing with an async dialog method. However, in the async task that I call to present the dialog, there are conditions where I return a boolean value immediately instead awaiting the return of a dialog task method. In those cases an exception is thrown:
System.InvalidOperationException: 'Cannot set Visibility to Visible or call Show, ShowDialog, Close, or WindowInteropHelper.EnsureHandle while a Window is closing.'
It seems that this is because the async task is returning synchronously and calling Close() on the window instead of calling the rest of the code as a continuation. Besides just wrapping Close() in a try/catch or adding a Task.Delay() in my function before returning my bool, is there a way to detect if I should call Close() on my window? (ie. if the task returned synchronously)
Or...am I conceptually missing something in the async/await pattern?
Here is my code:
private bool _closeConfirmed;
private async void MainWindow_OnClosing(object sender, CancelEventArgs e)
{
//check if flag set
if(!_closeConfirmed)
{
//use flag and always cancel first closing event (in order to allow making OnClosing work as as an async function)
e.Cancel = true;
var cancelClose = await mainViewModel.ShouldCancelClose();
if(!cancelClose)
{
_closeConfirmed = true;
this.Close();
}
}
}
Here's what the async function looks like:
public async Task<bool> ShouldCancelClose()
{
if(something)
{
var canExit = await (CurrentMainViewModel as AnalysisViewModel).TryExit();
if (!canExit) //if user cancels exit
return true;
//no exception
return false;
}
//this causes exception
return false;
}