在任务中等待异步/等待

时间:2014-07-16 09:34:52

标签: c# .net task-parallel-library task async-await

我在我的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()的呼叫完成。 我怎么让它实际等待?

3 个答案:

答案 0 :(得分:89)

不鼓励Task.Factory.StartNewasync-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。