.net 在HttpContent中,为什么ReadFromJsonAsync是一个异步方法?

a2mppw5e  于 2022-12-24  发布在  .NET
关注(0)|答案(2)|浏览(461)

我对HttpContent.ReadFromJsonAsynclink)有疑问
在向端点发出请求常见方式中,可以这样做:

var response = await Http.GetAsync(path...);
if (!response.IsSuccessStatusCode)
{
    [do something]
}
else
{
     myObject = (await response.Content.ReadFromJsonAsync<MyObject>())!;
}

我很难理解为什么当我想要获取对象时,需要执行另一个等待操作。在我的脑海中,我已经在GetAsync mehotd中得到了响应,缺少的只是反序列化对象。我理解等待与将json转换为对象无关,而是与网络有关。
我试图在MS官方文档中找出这种行为的原因,但我什么也找不到。
在google上搜索,我发现即使响应的内容在调用ReadFromJsonAsync时已经收到,该方法仍然需要从网络读取响应的内容,并解析该内容以便将其反序列化为指定的对象类型。
但不明白为什么这是必要的,也不知道内容"在哪里",我知道response.Content.ReadFromJsonAsync没有发出新的网络请求,那么后面发生了什么?
它是暂时存储在某个套接字中吗?(或者这么想是无稽之谈吗?)读它有时间限制吗?
谢谢!

umuewwlo

umuewwlo1#

例如,HttpClient.GetAsync的重载接受HttpCompletionOption参数,该参数允许 GetAsync 在读取响应标头后立即完成,而响应的内容尚未完全接收。
因此,ReadFromJsonAsync 是异步的是有意义的,因为阅读 HttpResponseMessage.Content 可能成为I/O绑定的操作,包括等待和接收响应的完整内容。

knpiaxh1

knpiaxh12#

HTTP将响应分解为多个帧,并在元数据和响应数据之间做出了明确的区分,第一组帧包含状态代码和头,通常您可以仅根据这些信息来决定如何处理响应。

Mozilla documentation for HTTP Messages
在C#中,一旦接收到所有的头帧,就可以从请求返回响应对象。
默认情况下,GetAsync方法 * 将 * 等待所有响应数据返回,但是有一些重载允许您在收到头后立即开始处理响应。

为什么不一开始就等待所有数据呢?

请求的内容可能很大!假设您要下载一个4Gb的图像,并将其保存到本地PC上的一个文件中。如果HTTP实现等待所有 Dataframe 被接收,您最终将使用至少4Gb的RAM来缓冲数据。
内容通过流公开,而不是等待 Dataframe 。数据附加到缓冲区,并由应用程序根据需要从缓冲区读取。从流阅读是异步操作,因为您可能正在等待接收更多的帧。这里的关键区别是缓冲区可以有一个相对较小的大小限制。如果响应包含的数据超出缓冲区的容量,则必须多次读取流-这是API的正常用法。

相关问题