I\'m having a problem where I cannot await an asynchronous function inside of the FormClosing event which will determine whether the form close should continue. I have crea
Dialogs handle messages while still keeping the current method on the stack.
You could show a "Saving..." Dialog in your FormClosing handler, and run the actual saving-operation in a new task, which programmatically closes the dialog once it's done.
Keep in mind that SaveAsync is running in a non-UI Thread, and needs to marshal any access UI elements via Control.Invoke (see call to decoy.Hide below). Best would probably be to extract any data from controls beforehand, and only use variables in the task.
protected override void OnFormClosing(FormClosingEventArgs e)
{
Form decoy = new Form()
{
ControlBox = false,
StartPosition = FormStartPosition.CenterParent,
Size = new Size(300, 100),
Text = Text, // current window caption
};
Label label = new Label()
{
Text = "Saving...",
TextAlign = ContentAlignment.MiddleCenter,
Dock = DockStyle.Fill,
};
decoy.Controls.Add(label);
var t = Task.Run(async () =>
{
try
{
// keep form open if saving fails
e.Cancel = !await SaveAsync();
}
finally
{
decoy.Invoke(new MethodInvoker(decoy.Hide));
}
});
decoy.ShowDialog(this);
t.Wait(); //TODO: handle Exceptions
}