如何在没有Task.Result的情况下通过await获取异步方法的确切结果?

时间:2015-10-17 18:04:20

标签: c# async-await

我想尝试异步和等待,但我有一个惨败。 我有一个方法,需要异步运行两个方法(它部分工作)

public void Run()
{
            Task[] tasks = new Task[2];
            tasks[0] = Task.Factory.StartNew(DisplayInt);
            tasks[1] = Task.Factory.StartNew(DisplayString);

            //block thread until tasks end
            Task.WaitAll(tasks);
}

使用两种方法

public async void DisplayInt()
    {
        Task<int> task = new Task<int>(
            () => 10);
        task.Start();
        Console.WriteLine(await task);
    }

    public async void DisplayString()
    {
        Task<string> task = new Task<string>(
           () => "ok" );
        task.Start();
        Console.WriteLine(await task);
   }

通常我会得到下一个结果:1)10 ok

或 2)确定 10

但有时候 我没有得到任何东西

如何在不使用task.Result的情况下通过await获取异步方法的确切结果,或者它不会发生?

2 个答案:

答案 0 :(得分:6)

我建议您阅读一些介绍性文章,例如我自己的async intro,然后使用我的MSDN article on async best practices进行跟进。如果你只是敲打代码,那么你最终会感到非常痛苦。

特别是,您should not use Task.Factory.StartNewthe Task constructornor Task.Start;你应该避免async void(所有链接都在我的博客上,我详细解释了为什么)。

回答你的实际问题:

  

如何在不使用task.Result的情况下通过await获取异步方法的确切结果,或者它不会发生?

要从任务中获取结果,您可以异步等待任务完成(通过await),或者您可以同步(阻止)等待任务完成(通过Result )。没有&#34;其他方式&#34;,如果这是你要求的。

答案 1 :(得分:1)

欢迎来到SO ......

嗯,在你的情况下,两个任务都需要更多的时间来初始化它们,然后在里面运行方法。这就是为什么有时第二个任务在第一个任务完成之前完成(如果它在较短的时间内初始化)。如果您将DisplayString方法更改为:

    public static async void DisplayString()
    {
        Task<string> task = new Task<string>(
            () => { Thread.Sleep(10); return "ok"; });
        task.Start();
        Console.WriteLine(await task);
    }

现在DisplayString方法现在需要大约10毫秒来执行它将始终导致:

10    
ok

P.S。 正如Stephen Cleary所指出的,您可以阅读一些关于async / await的基本文章。我还建议在WinForms项目上进行测试,而不是使用Console进行测试。