在任务中等待async/await
本文关键字:await async 等待 任务 | 更新日期: 2023-09-27 18:13:06
我在main()
中有这个结构,它创建了
var tasks = new List<Task>();
var t = Task.Factory.StartNew(
async () =>
{
Foo.Fim();
await Foo.DoBar();
});
//DoBar not completed
t.Wait();
//Foo.Fim() done, Foo.DoBar should be but isn't
然而,当我将.Wait
替换为t时,它不会等待对DoBar()
的调用完成。我如何让它真正等待?
不鼓励使用Task.Factory.StartNew
和async-await
,您应该使用Task.Run
代替:
var t = Task.Run(
async () =>
{
Foo.Fim();
await Foo.DoBar();
});
Task.Factory.StartNew
api是在基于任务的异步模式(TAP)和async-await
之前构建的。它将返回Task<Task>
,因为您正在启动一个带有lambda表达式的任务,该表达式恰好是异步的,因此返回一个任务。Unwrap
将提取内部任务,但Task.Run
将隐式地为您完成。
要进行更深入的比较,总有一篇相关的Stephen Toub文章:任务。Run vs Task.Factory.StartNew
似乎我通过Unwrap()
任务获得了所需的功能。我不太确定我明白这背后的原因,但我想它是有效的。
var t = Task.Factory.StartNew(
async () =>
{
Foo.Fim();
await Foo.DoBar();
}).Unwrap();
编辑:我已经找了Unwrap()
的描述:Creates a proxy Task that represents the asynchronous operation of a Task<Task<T>>
我认为这是传统的任务所做的,但如果我需要调用unwrap,我认为这很好。
我最近遇到了类似的问题,并发现所有你需要做的就是让DoBar()
返回一些值并使用. result而不是等待。
var g = Task.Run(() => func(arg));
var val = g.Result;
这将等待func
返回其输出并将其赋值给val。