我有一个WPF应用程序,按下按钮并执行以下代码:
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
new Thread(
async () =>
{
Action lambda = async () =>
{
await Task.Delay(5000);
MessageBox.Show("Lambda done");
};
await this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, lambda).Task;
MessageBox.Show("Dispatch done");
}).Start();
}
DispatcherOperation.Task
的{p> MSDN documentation说:Gets a Task<TResult> that represents the current operation.
(这不是Task<TResult>
tho:/)MessageBox.Show("Dispatch done");
只会在lambda完成后执行。但事实并非如此。按下按钮后会立即显示带有“Dispatch done”文本的MessageBox,并且按照预期在5秒后显示带有“Lambda done”文本的文本。
有人可以解释这个吗?我不明白为什么会这样。
答案 0 :(得分:3)
这一行:
Action lambda = async ...
正在创建async void
lambda而不是async Task
lambda。 async void
的(许多)问题之一是没有(简单)方法告诉它何时完成。出于这个原因,我在MSDN文章中提到了"avoid async void" is one of the best practices。
我没有尝试过,但我怀疑Dispatcher.BeginInvoke
只能接受Action
个代表(而不是更加异步友好的Func<Task>
),在这种情况下可能会更好使用Dispatcher.Invoke
并传递Func<Task>
。但是,在我自己的代码中,我完全避免使用Dispatcher
;我发现它鼓励更糟糕的代码。请考虑使用Dispatcher
和/或await
。
Progress<T>