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
PerformClick
if the eventhandler isasync
. It will notawait
!Never call an
async
eventhandler directly. It will notawait
!
What's left is the lack of documentation on this:
Button.PerformClick
should have a Warning on the doc page:
Button.PerformClick "Calling PerformClick will not await async eventhandlers."
- Calling an
async void
method (or eventhandler) should give a compiler Warning: "You're calling an async void method, it will not be awaited!"