简体   繁体   English

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

[英]How to get exactly result from async methods via await without Task.Result?

I wanted to experiment with async and await but I had a fiasco. 我想尝试异步和等待,但我有一个惨败。 I have the method which need to run two methods asynchronously(it works partly) 我有方法需要异步运行两个方法(它部分工作)

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);
}

And two methods which are used 并使用了两种方法

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);
   }

And usually I got next results:1) 10 ok 通常我得到下一个结果:1)10 ok

or 2)ok 10 或2)确定10

but sometimes I got 3)nothing 但有时我什么都没有

How to get exactly result from async methods via await without using task.Result or it cannot happen? 如何在不使用task.Result的情况下通过等待获得异步方法的确切结果,或者它不会发生?

I recommend you read some introductory articles like my own async intro , and follow that up with my MSDN article on async best practices . 我建议您阅读一些介绍性文章,例如我自己的async介绍 ,并在我的MSDN文章中了解异步最佳实践 If you just bang out code, you're going to end up with a lot of pain. 如果你只是敲打代码,你最终会遇到很多痛苦。

In particular, you should not use Task.Factory.StartNew , the Task constructor , nor Task.Start ; 特别是,您不应该使用Task.Factory.StartNewTask构造函数也不 应该使用 Task.Start ; and you should avoid async void (all links are to my blog where I explain in detail why ). 并且你应该避免async void (所有链接都是我的博客,我详细解释了为什么 )。

To answer your actual question: 要回答您的实际问题:

How to get exactly result from async methods via await without using task.Result or it cannot happen? 如何在不使用task.Result的情况下通过等待获得异步方法的确切结果,或者它不会发生?

To get the result from a task, you can either asynchronously wait for the task to complete (via await ), or you can synchronously (blocking) wait for the task to complete (via Result ). 要从任务中获取结果,您可以异步等待任务完成(通过await ),也可以同步(阻塞)等待任务完成(通过Result )。 There's no "other way", if that's what you're asking. 没有“其他方式”,如果这就是你所要求的。

Welcome to SO... 欢迎来到SO ......

Well, in your case for both tasks it takes more time to initialize them, then to run the method inside. 好吧,在你的情况下,两个任务都需要更多的时间来初始化它们,然后在里面运行方法。 That's why sometimes second task finishes before the first one (if it was initialized in shorter time). 这就是为什么有时第二个任务在第一个任务完成之前完成(如果它在较短的时间内初始化)。 If you change your DisplayString method to : 如果您将DisplayString方法更改为:

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

As now DisplayString method now takes around 10 ms to execute It'll will always result in : 因为现在DisplayString方法现在需要大约10毫秒来执行它将始终导致:

10    
ok

PS As pointed by Stephen Cleary you can read some basic articles about async / await . PS正如Stephen Cleary所指出的,您可以阅读一些关于async / await基本文章。 I'd also recommend to test it on WinForms projects rather then doing it with Console . 我还建议在WinForms项目上测试它,而不是使用Console

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM