异步等待阻塞,有什么问题?

Dou*_*oid 0 .net c# async-await

我正在尝试测试.NET的async/await功能.我在LinqPad中设置了一个小测试:

void Main(string[] args)
{
    Test.DoStuff().Wait();
}

// Define other methods and classes here
public class Test
{
    public async static Task DoStuff()
    {
        string s1 = "Hello 1";
        string s2 = "Hello 2";
        var s3 = await Test.Gimme();
        string s4 = "Hello 4";

        Console.WriteLine(s1);
        Console.WriteLine(s2);
        Console.WriteLine(s3);
        Console.WriteLine(s4);
    }

    public async static Task<string> Gimme()
    {
        return await Task.Run<string>(() => RetString());
    }

    public static string RetString()
    {
        Console.WriteLine("Begin");

        for (int i = 0; i < 90000000; i++)
        {
            string s = "FOO";
            s = s + s;
            s = s + s;
        }

        Console.WriteLine("End");
        return "Task Hello 3!";
    }
}
Run Code Online (Sandbox Code Playgroud)

根据我的理解,我认为代码将被执行,直到再次使用s3 => Console.WriteLine(s3);

我错过了什么?!我认为await关键字是这样的,只要等待的结果没有被使用,程序就会继续做它的东西.

也许我正在实施任务错误?!

Dav*_*vid 7

我认为await关键字是这样的,只要等待的结果没有被使用,程序就会继续做它的东西.

你误会了.该await关键字将等待该操作.也就是说,Task关键字等待该任务的结果,而不是返回可以在稍后完成操作的那个.(在这种情况下是一个字符串.)

所以当你这样做时:

var s3 = await Test.Gimme();
string s4 = "Hello 4";
Run Code Online (Sandbox Code Playgroud)

async操作结果可用之前,第二行不会执行.与此相反:

var s3 = Test.Gimme();
string s4 = "Hello 4";
Run Code Online (Sandbox Code Playgroud)

哪个等待操作完成,而只是将引用放入Task<string>in s3,这可能在以后完成(等待).

这里的想法是,DoStuff()方法本身将按照命令式编写的顺序执行代码,就像任何其他代码一样.但是该代码调用的东西可能是异步的,因此反过来调用的代码可以DoStuff()选择以异步方式处理它.

大多数async方法在逻辑上是同步的,但是包装底层异步操作并将选项暴露给更高级别以不阻止这些操作.保持事物应该"一直异步"的口头禅,许多这样的方法提供"传递ascynchronicity"并允许顶级UI异步处理底层I/O.


Eri*_*ert 5

我错过了什么?!我认为await关键字是这样的,只要等待的结果没有被使用,程序就会继续做它的东西.

你是对的; 你的困惑是"做它的东西"的意思.在等待结果时完成的"东西" 是DoStuff 调用者的"东西" ,即Main.当DoStuff因为任务没有完成而无法取得进展时,调用者会做什么? 它叫Wait.这就是发生的事情!

你说你想要等待结果,这意味着你希望调用者在异步处理任务时做它做的任何事情.调用者说:"我无所事事,只能同步等待*.如果调用者在调用Wait之前做了其他工作,那么你会看到工作正在完成.