在Dispatcher.BeginInvoke()中使用异步/等待 [英] Using async/await with Dispatcher.BeginInvoke()

查看:668
本文介绍了在Dispatcher.BeginInvoke()中使用异步/等待的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个执行一些await操作的代码的方法:

I have a method with some code that does an await operation:

public async Task DoSomething()
{
    var x = await ...;
}

我需要该代码在Dispatcher线程上运行.现在,可以等待Dispatcher.BeginInvoke()了,但是我不能将lambda标记为async以便从内部运行await,就像这样:

I need that code to run on the Dispatcher thread. Now, Dispatcher.BeginInvoke() is awaitable, but I can't mark the lambda as async in order to run the await from inside it, like this:

public async Task DoSomething()
{
    App.Current.Dispatcher.BeginInvoke(async () =>
        {
            var x = await ...;
        }
    );
}

在内部async上,出现错误:

无法将lambda表达式转换为类型"System.Delegate",因为它不是委托类型.

Cannot convert lambda expression to type 'System.Delegate' because it is not a delegate type.

如何在Dispatcher.BeginInvoke()中使用async?

推荐答案

其他答案可能引入了晦涩的错误.这段代码:

The other answer may have introduced an obscure bug. This code:

public async Task DoSomething()
{
    App.Current.Dispatcher.Invoke(async () =>
    {
        var x = await ...;
    });
}

使用 Dispatcher.Invoke(Action callback) 覆盖Dispatcher.Invoke的形式,在这种特殊情况下,该形式接受async void lambda.这可能会导致非常意外的行为,因为通常会发生在 async void方法中.

uses the Dispatcher.Invoke(Action callback) override form of Dispatcher.Invoke, which accepts an async void lambda in this particular case. This may lead to quite unexpected behavior, as it usually happens with async void methods.

您可能正在寻找这样的东西:

You are probably looking for something like this:

public async Task<int> DoSomethingWithUIAsync()
{
    await Task.Delay(100);
    this.Title = "Hello!";
    return 42;
}

public async Task DoSomething()
{
    var x = await Application.Current.Dispatcher.Invoke<Task<int>>(
        DoSomethingWithUIAsync);
    Debug.Print(x.ToString()); // prints 42
}

在这种情况下, Dispatch.Invoke<Task<int>> 接受Func<Task<int>>自变量,并返回相应的Task<int>,它是可等待的.如果您不需要从DoSomethingWithUIAsync返回任何内容,只需使用Task而不是Task<int>.

In this case, Dispatch.Invoke<Task<int>> accepts a Func<Task<int>> argument and returns the corresponding Task<int> which is awaitable. If you don't need to return anything from DoSomethingWithUIAsync, simply use Task instead of Task<int>.

或者,使用 Dispatcher.InvokeAsync 方法.

Alternatively, use one of Dispatcher.InvokeAsync methods.

这篇关于在Dispatcher.BeginInvoke()中使用异步/等待的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆