同步和异步等待不是一回事吗?

Is synchronous and await asynchronous just not the same thing?

我不知道这个问题是否愚蠢,但我已经看到了很多异步、等待和同步方法的不同场景。我所了解的是,您根本没有“阻止线程”执行其他任务。

但是,当您在任务上使用 await 时,不就是简单地等待值返回,在这种情况下同步同步吗?

我正在使用 .NET 框架

遇到等待时,执行不会继续,但执行代码的线程可以做其他事情,稍后可以回来继续。

通过异步操作,网络服务器可以处理比它拥有的线程更多的请求,因为当处理一个请求时 'blocked' - 例如从数据库中获取一些东西 - 线程可以接收另一个请求并开始处理它。

我希望这来自 What happens under the covers,有助于说明差异:

On the C# side of things, the compiler transforms your code into a state machine that keeps track of things like yielding execution when an await is reached and resuming execution when a background job has finished.

when you're using an await on a task isn't that just simply waiting for the value to come back and in that case sync synchronous?

一种思路是方法等待异步操作完成,而线程则不会。异步代码释放了线程,这为您提供了两个好处之一,具体取决于您正在编写的应用程序的类型:

  • GUI 应用程序能够保持其 UI 线程空闲,从而防止出现“冻结 UI”/“应用程序未响应”问题。
  • ASP.NET(和其他服务器)应用程序能够在其线程池中保留更多可用线程,这意味着它们可以更快地扩展并进一步扩展(即处理更多并发请求)。

Is synchronous and await asynchronous just not the same thing?

代码确实看起来很相似,而且是特意这样做的(以使异步代码更易于编写和维护)。但相似性实际上是由于串行操作性质:A() then B()类似于await A() then await B()。所以代码的 serial/imperative 性质是相似的;它们在同步和异步方面完全不同。

您可以认为通过 await 关键字您立即 returning Task(或类似的)而不是实际值(参见 )。我们必须return一个Task或类似的因为实际的return值可能还不知道...

为了向调用者说明 returning,这里是我的其他答案中的示例,已翻译成 C#:

class Program
{
    static async Task<string> MyAsyncFunc()
    {
        int i;

        for( i = 0; i < 1000000; i++ ) ; // create some synchronous delay

        // Create an asynchronous task that we can await on later...
        var innerTask = ( ( Func<Task<string>> )( async () => {
            await Task.Delay( 1000 );
            return "done!";
        } ) )();

        Console.WriteLine( "message inside f before returning, still synchronous, i = " + i );

        // let's await and at the same time return a Task to the caller
        var result = await innerTask;
        Console.WriteLine( "message inside f after await, asynchronous now" );

        Console.WriteLine( result ); // "done!"

        return "function finished";
    }

    static void Main()
    {
        var myresult = MyAsyncFunc();
        Console.WriteLine( "message outside f, immediately after calling f" );
        System.Threading.Thread.Sleep( 2000 ); // Create delay to prevent exit before asynchronous writing of lines.
    }
}

对应的输出为:

message inside f before returning, still synchronous, i = 1000000
message outside f, immediately after calling f
message inside f after await, asynchronous now
done!

请注意,Main() 在实际 return 值 "function finished" 被 return 编辑之前就已经在函数调用之后继续执行。

when you're using an await on a task isn't that just simply waiting for the value to come back and in that case sync synchronous?

这里有一个根本性的误解。 await 不是 Wait() 指令。它更接近于 return。如果任务还没有完成,await returns 立即将控制权交给调用者.

您的方法的其余部分作为单独的任务发布,无法保证何时执行。这就是它异步的原因。