我在我的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()
的呼叫完成。
我怎么让它实际等待?
答案 0 :(得分:89)
不鼓励Task.Factory.StartNew
与async-await
一起使用,您应该使用Task.Run
代替:
var t = Task.Run(
async () =>
{
Foo.Fim();
await Foo.DoBar();
});
Task.Factory.StartNew
api是在Task-based Asynchronous Pattern (TAP)和async-await
之前构建的。它将返回Task<Task>
,因为您正在使用lambda表达式启动任务,该表达式恰好是异步的,因此返回任务。 Unwrap
将提取内部任务,但Task.Run
将隐式为您执行此任务。
为了进行更深入的比较,总有一篇相关的Stephen Toub文章:Task.Run vs Task.Factory.StartNew
答案 1 :(得分:5)
似乎我通过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>>
我认为传统上这是任务所做的,但如果我需要打电话给我打算,我认为那很好。
答案 2 :(得分:1)
我最近遇到了类似的问题并且发现你需要做的就是让DoBar()
返回一些值并使用.Result而不是等待。
var g = Task.Run(() => func(arg));
var val = g.Result;
这将等待func
返回其输出并将其分配给val。