首页 > 解决方案 > Is Dispatcher.BeginInvoke() without await still executed asynchronous?

问题描述

I have a hard time understanding the connection between the asynchrnous methods of the dispatcher and async/await.

In my case I have an event handler that executes an operation on the dispatcher:

 private void OnEventOccurred(object sender, EventArgs e)
 {
     someControl.Dispatcher.BeginInvoke(DispatcherPriority.Background, SomeLongRunningOperation());
 }

This should not block the UI thread, right? At least it feels like it in our application. What is the difference to the version with async/await?

 private async void OnEventOccurred(object sender, EventArgs e)
 {
     await someControl.Dispatcher.BeginInvoke(DispatcherPriority.Background, SomeLongRunningOperation());
 }

This also works and doesn't seem to make a difference in terms of UI responsiveness.

标签: c#wpfasync-awaitdispatcher

解决方案


BeginInvoke as the name suggests is always asynchronous. You're asking the Dispatcher (UI thread) to perform this operation, in your case long running, without blocking the calling thread. If you decided to use the Invoke instead, the calling thread gets blocked until the Dispatcher is done with executing the delegate you provided.

BeginInvoke does not imply that the work is done asynchronously on a different thread. What you would want to do is start this SomeLongRunningOperation on a different task and return it using the async await pattern as you tried in the second example. Something like this:

 private async void OnEventOccurred(object sender, EventArgs e)
 {
     await Task.Run(SomeLongRunningOperation());
 }

推荐阅读