I have a problem in a Windows Forms application where I use PerformClick to call an async event handler. It seems that the event handler doesn't await but just returns immediately. I have created this simple application to show the problem (it's just a form with 3 buttons, easy to test yourself):
string message = "Not Started";
private async void button1_Click(object sender, EventArgs e)
{
await MyMethodAsync();
}
private void button2_Click(object sender, EventArgs e)
{
button1.PerformClick();
MessageBox.Show(message);
}
private void button3_Click(object sender, EventArgs e)
{
MessageBox.Show(message);
}
private async Task MyMethodAsync()
{
message = "Started";
await Task.Delay(2000);
message = "Finished";
}
The interesting problem here is, what do you think message shows, when I click Button2?
Surprisingly, it shows "Started", not "Finished", as you would expect. In other Words, it doesn't await MyMethod(), it just starts the Task, then continues.
Edit:
In this simple code I can make it Work by calling await Method() directly from Button2 event handler, like this:
private async void button2_Click(object sender, EventArgs e)
{
await MyMethodAsync();
MessageBox.Show(message);
}
Now, it waits 2 seconds and displays 'Finished'.
What is going on here? Why doesn't it work when using PerformClick?
Conclusion:
Ok, now I get it, the conclusion is:
Never call
PerformClickif the eventhandler isasync. It will notawait!Never call an
asynceventhandler directly. It will notawait!
What's left is the lack of documentation on this:
Button.PerformClickshould have a Warning on the doc page:
Button.PerformClick "Calling PerformClick will not await async eventhandlers."
- Calling an
async voidmethod (or eventhandler) should give a compiler Warning: "You're calling an async void method, it will not be awaited!"