有时候教程会指导读者实现自己的异步方法,例如下面这段代码:
async public static Task GetHttpResponseAsync()
{
using (HttpClient httpClient = new HttpClient())
{
HttpResponseMessage response = await httpClient.GetAsync(...);
Console.WriteLine(response.Something);
}
}
我明白的是异步工作的一般原理,但是没有任何教程解释内部实现方式。
httpClient.GetAsync(...);
这对于理解异步代码的工作原理非常重要。让我感到好奇的是,GetAsync(或其他异步方法)的内部操作是否被注册在某种容器中以执行此代码?异步方法是否必须由操作系统支持(例如,它使用Windows API)?如果我想实现自己的异步文件下载器(从磁盘上而且没有.NET框架的重要部分),我应该如何实现它?我需要在某个地方注册我的方法以供进一步调用吗?
对我来说很清楚,编译器在内部创建状态机,并在DoSomething()方法完成后再次调用此状态机以恢复执行await后的代码。
另外,我不清楚的是异步代码如何在同一线程上运行。我认为维护状态机必须在同一线程上进行,但httpClient.GetAsync()中的代码如何在同一线程上运行而不会中断其他操作(例如GUI)呢?在所有情况下,必须有某些东西使此代码在单独的线程上运行。我错了吗?我错过了什么?
我的问题的额外解释:就我所知和理解的JavaScript,异步方法通过将它们注册在某种容器中(该容器在单独的线程上逐个运行它们)来运行,该容器执行此方法。方法执行完成后,结果会返回到用户上下文中。我想知道这里的工作方式是否相同?
async/await
是一种程序级别的特性,使得编写与可等待对象进行交互的代码更加人性化。然而,异步本身是您的程序与任何实体进行通信的接口的一个特性。同步接口会让您等待所需的任何响应,而异步接口则接受您的请求并提供了一种机制,在准备好时回调您。异步接口很好地转换为可等待对象,而同步接口则不行。 - Asad Saeeduddin