我有一个方法,其中包含一些执行await
操作的代码:
public async Task DoSomething()
{
var x = await ...;
}
我需要在Dispatcher线程上运行该代码。现在,Dispatcher.BeginInvoke()
是等待的,但我无法将lambda标记为async
,以便从内部运行await
,如下所示:
public async Task DoSomething()
{
App.Current.Dispatcher.BeginInvoke(async () =>
{
var x = await ...;
}
);
}
在内部async
上,我收到错误:
无法将lambda表达式转换为'System.Delegate'类型,因为它不是委托类型。
如何在async
内使用Dispatcher.BeginInvoke()
?
答案 0 :(得分:46)
other answer可能引入了一个模糊的错误。这段代码:
public async Task DoSomething()
{
App.Current.Dispatcher.Invoke(async () =>
{
var x = await ...;
});
}
使用Dispatcher.Invoke
覆盖形式的async void
,在这种特殊情况下接受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
}
lambda。这可能会导致非常意外的行为,因为它通常发生在Dispatcher.Invoke(Action callback)
。
你可能正在寻找这样的东西:
Func<Task<int>>
在这种情况下,async void
methods接受Task<int>
参数并返回等待的DoSomethingWithUIAsync
。如果您不需要从Task
返回任何内容,只需使用Task<int>
代替{{1}}。
或者,使用Dispatch.Invoke<Task<int>>
方法之一。
答案 1 :(得分:-4)
使用Dispatcher.Invoke()
public async Task DoSomething()
{
App.Current.Dispatcher.Invoke(async () =>
{
var x = await ...;
});
}