If I declare my event handlers as async void
, will they be called synchronously or asynchronously by the .NET framework?
I.e., given the following code:
async void myButton_click(object sender, EventArgs e) {
do stuff
await longRunning()
do more stuff
}
Can I be sure that the "do stuff" line will be executed on the GUI thread?
You can register both synchronous and asynchronous event handlers concurrently to the same event. The Event Manager framework executes the registered event handlers in whichever mode you configure them to operate, always executing synchronous event handlers first.
NET events do not support async Task as a result type! Instead, you have to cast event handlers as async void if you want to run async code inside of an event handler method and to comply with the classic .
With async void methods, there is no Task object, so any exceptions thrown out of an async void method will be raised directly on the SynchronizationContext that was active when the async void method started. Figure 2 illustrates that exceptions thrown from async void methods can't be caught naturally.
You use the void return type in asynchronous event handlers, which require a void return type. For methods other than event handlers that don't return a value, you should return a Task instead, because an async method that returns void can't be awaited.
Event handlers will be called synchronously and doesn't wait(await) till the event handler completes, but waits till the event handler returns.
If previous sentence was confusing enough, I'll try to explain it clear. Asynchronous methods completes when all the await points are executed and the end of the method body has reached or any return statement is executed(Ignoring the exception). But asynchronous method returns as soon as you hit the first await statement for the Task
which is not yet completed. In other words asynchronous method can return several times but can complete only once.
So now we know when does a asynchronous method completes and returns. Event handler will assume your method has completed as soon as it returns not when it actually completes.
As soon as your event handler reaches first await
statement, it will return, if there are more methods attached to same event handler, it will continue executing them without waiting for the asynchronous method to complete.
Yes, do stuff
will be executed in UI thread if the UI thread fires the event and yes do more stuff
will also be executed in UI thread as long as longRunning().ConfigureAwait(false)
isn't called.
They will be invoked just as any other non-async-await
method is invoked:
Click(this, EventArgs.Empty);
Because this specific event handler is an async
method the call would run synchronously until an await
is reached and the rest would be a continuation. That means that do stuff
is executed synchronously on the GUI thread. The caller then moves on without the knowledge that the async
operation hasn't completed yet.
do more stuff
would also be executed on the GUI thread, but for a different reason. The SynchronizationContext
in a GUI environment makes sure the continuations would be posted to the single GUI thread, unless you explicitly tell it not to with await longRunning().ConfigureAwait(false)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With