我的
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 文章:Task.Run 与 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。