c# - DispatcherOperation.Task 立即返回

标签 c# wpf multithreading dispatcher

我有一个 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();
}

MSDN documentationDispatcherOperation.Task说:Gets a Task<TResult> that represents the current operation. (这不是 Task<TResult> :/)
所以我认为等待这意味着 MessageBox.Show("Dispatch done");只会在 lambda 完成后执行。然而,事实并非如此。按下按钮后,就会显示带有“Dispatch done”文本的 MessageBox,并且如预期那样,5 秒后会显示带有“Lambda done”文本的 MessageBox。

有人能解释一下吗?我不明白为什么会发生这种情况。

最佳答案

这一行:

Action lambda = async ...

正在创建一个async void lambda 而不是 async Task lambda 。 async void 的(许多)问题之一是没有(简单)方法来判断它何时完成。为此,"avoid async void" is one of the best practices在我关于该主题的 MSDN 文章中。

我没有尝试过,但我怀疑 Dispatcher.BeginInvoke只能取Action委托(delegate)(而不是更异步友好的 Func<Task> ),在这种情况下,最好使用 Dispatcher.Invoke 。并通过 Func<Task> 。不过,在我自己的代码中,我避免 Dispatcher完全;我发现它鼓励更糟糕的代码。而不是Dispatcher ,考虑使用await和/或Progress<T> .

关于c# - DispatcherOperation.Task 立即返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35796877/

相关文章:

c# - 在 Windows 服务中执行任务循环的最佳方法

java - 用于 coSTLy 请求的请求聚合器/中间层设计模式

c# - 如何不丢失绑定(bind)源更新?

c# - 如何实现回滚功能?

c# - 在不使用 Excel.Interop 的情况下在 Excel 上编写和执行 VBA 宏

c# - WPF 在触发器上更改 Grid.ColumnSpan

JavaFX:在单独的线程中运行任务不允许运行其他任何东西

c# - 如何使用 SQL file streaming win32 API 和支持 WCF streaming

wpf - 如何使 TreeViewItem 向右水平扩展?

c# - 如何在 WPF Canvas 上绘制网格线?