【问题标题】:How to get exactly result from async methods via await without Task.Result?如何在没有Task.Result的情况下通过await从异步方法中获得准确的结果?
【发布时间】:2015-10-17 18:04:20
【问题描述】:

我想尝试 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

但有时 我得到了 3) 什么都没有

如何在不使用 task.Result 的情况下通过 await 从异步方法获得准确的结果,否则它不会发生?

【问题讨论】:

标签: c# async-await


【解决方案1】:

我建议您阅读一些介绍性文章,例如我自己的 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)。没有“其他方式”,如果这就是你要问的。

【讨论】:

    【解决方案2】:

    欢迎来到...

    嗯,在你的情况下,这两个任务都需要更多时间来初始化它们,然后运行内部的方法。这就是为什么有时第二个任务在第一个任务之前完成(如果它在更短的时间内初始化)。如果您将 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
    

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

    【讨论】:

    • 基于睡眠的同步并不是一个很好的做法——我认为您应该补充一点,它仅用于演示目的。没有经验的人可能会将您的示例作为使用的模式。
    猜你喜欢
    • 2015-11-21
    • 2017-06-08
    • 2019-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多