【问题标题】:WPF Dispatcher.InvokeAsync() strange behavior with async delegateWPF Dispatcher.InvokeAsync() 异步委托的奇怪行为
【发布时间】:2018-06-30 07:43:30
【问题描述】:

如果您有异步方法,如下所示:

    private async Task DoAsync()
    {
        Console.WriteLine(@"(1.1)");
        Thread.Sleep(200);
        Console.WriteLine(@"(1.2)");
        await Task.Delay(1000);
        Console.WriteLine(@"(1.3)");
    }

然后你用 Dispatcher 异步调用它:

        Console.WriteLine(@"(1)");
        await Application.Current.Dispatcher.InvokeAsync(DoAsync);
        Console.WriteLine(@"(2)");

您将获得的输出将是: (1) (1.1) (1.2) (2) (1.3)

如果您使用 Dispatcher.BeginInvoke() 并且您将等待 Completed 事件,效果将是相同的(这是预期的):

        Console.WriteLine(@"(1)");
        var dispatcherOp = Dispatcher.BeginInvoke(new Func<Task>(DoAsync));
        dispatcherOp.Completed += (s, args) =>
        {               
        Console.WriteLine(@"(2)");
        };

我们在这里看到的是 DoAsync() 方法中的 await 使 Dispatcher 相信操作已结束。

我的问题:这是错误还是功能?你知道任何描述这种行为的文件吗?我找不到任何东西。

我不是在寻求解决方法。

【问题讨论】:

    标签: c# wpf async-await dispatcher


    【解决方案1】:

    这是您的代码中的一个错误,从Application.Current.Dispatcher.InvokeAsync(DoAsync); 返回的对象是Task&lt;Task&gt;,您只等待外部任务,而不是等待内部任务完成。这些情况就是.Unwrap() 的用途。

        Console.WriteLine(@"(1)");
        await Application.Current.Dispatcher.InvokeAsync(DoAsync).Unwrap();
        Console.WriteLine(@"(2)");
    

    您将得到的输出将是:(1) (1.1) (1.2) (1.3) (2)

    Unwrap 正在做的是有效地将您的代码转换为

        Console.WriteLine(@"(1)");
        await (await Application.Current.Dispatcher.InvokeAsync(DoAsync));
        Console.WriteLine(@"(2)");
    

    但格式更好看。

    有关文档,请参阅“How to: Unwrap a nested task

    【讨论】:

    • 感谢您提供的超级有用的答案! :)
    • 我可以写InvokeAsync(DoAsync).Task.Unwrap(),但不能写InvokeAsync(DoAsync).Unwrap()。我错过了什么吗?
    • @oleh:Dispatcher.InvokeAsync 返回 DispatcherOperation,而不是 Task,但是,它是可等待的,因此 await 关键字有效。获取任务并进行解包: Dispatcher.InvokeAsync(DoAsync).Task.Unwrap()
    • await await 比 Unwrap() 快,more info
    猜你喜欢
    • 1970-01-01
    • 2015-12-29
    • 1970-01-01
    • 2013-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多