何时或是否在调用 ReadAsStreamAsync 时处理 HttpResponseMessage?

时间:2023-02-03
本文介绍了何时或是否在调用 ReadAsStreamAsync 时处理 HttpResponseMessage?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我正在使用 System.Net.Http.HttpClient 进行一些客户端 HTTP 通信.我把所有的 HTTP 放在一个地方,从其余的代码中抽象出来.在一个实例中,我想将响应内容作为流读取,但流的使用者与 HTTP 通信发生的位置和流打开的位置完全隔离.在负责 HTTP 通信的地方,我处理了所有 HttpClient 的东西.

I am using the System.Net.Http.HttpClient to do some client-side HTTP communication. I've got all of the HTTP in one spot, abstracted away from the rest of the code. In one instance I want to read the response content as a stream, but the consumer of the stream is well insulated from where the HTTP communication happens and the stream is opened. In the spot responsible for HTTP communication I am disposing of all of the HttpClient stuff.

此单元测试将在 Assert.IsTrue(stream.CanRead) 处失败:

This unit test will fail at Assert.IsTrue(stream.CanRead):

[TestMethod]
public async Task DebugStreamedContent()
{
    Stream stream = null; // in real life the consumer of the stream is far away 
    var client = new HttpClient();        
    client.BaseAddress = new Uri("https://www.google.com/", UriKind.Absolute);

    using (var request = new HttpRequestMessage(HttpMethod.Get, "/"))
    using (var response = await client.SendAsync(request))
    {
        response.EnsureSuccessStatusCode();
        //here I would return the stream to the caller
        stream = await response.Content.ReadAsStreamAsync();
    }

    Assert.IsTrue(stream.CanRead); // FAIL if response is disposed so is the stream
}

我通常会尽可能方便地处理任何 IDisposable 但在这种情况下,处理 HttpResponseMessage 也会处理返回的 Stream来自 ReadAsStreamAsync.

I typically try to dispose of anything IDisposable at the earliest possible convenience but in this case, disposing the HttpResponseMessage also disposes the Stream returned from ReadAsStreamAsync.

因此,似乎调用代码需要了解响应消息和流并获得其所有权,或者我不处理响应消息并让终结器处理它.两种选择都感觉不对.

So it seems like the calling code needs to know about and take ownership of the response message as well as the stream, or I leave the response message undisposed and let the finalizer deal with it. Neither option feels right.

这个答案谈到不处理HttpClient.HttpRequestMessage 和/或 HttpResponseMessage 怎么样?

This answer talks about not disposing the HttpClient. How about the HttpRequestMessage and/or HttpResponseMessage?

我错过了什么吗?我希望让消费代码对 HTTP 一无所知,但留下所有这些未处理的对象违背了一年的习惯!

Am I missing something? I am hoping to keep the consuming code ignorant of HTTP but leaving all these undisposed objects around goes against year of habit!

推荐答案

所以看起来调用代码需要知道并采取响应消息和流的所有权,或者我离开未处理的响应消息并让终结器处理它.两种选择都感觉不对.

So it seems like the calling code needs to know about and take ownership of the response message as well as the stream, or I leave the response message undisposed and let the finalizer deal with it. Neither option feels right.

在这种特定情况下,没有终结器.HttpResponseMessageHttpRequestMessage 都没有实现终结器(这是一件好事!).如果您不处理它们中的任何一个,一旦 GC 启动,它们将被垃圾回收,一旦发生,它们的底层流的句柄将被回收.

In this specific case, there are no finalizers. Neither HttpResponseMessage or HttpRequestMessage implement a finalizer (and that's a good thing!). If you don't dispose of either of them, they will get garbage collected once the GC kicks in, and the handle to their underlying streams will be collected once that happens.

只要您正在使用这些对象,就不要丢弃.完成后,处理它们.无需将它们包装在 using 语句中,您始终可以在完成后显式调用 Dispose.无论哪种方式,消费代码都不需要了解 http 请求背后的任何知识.

As long as you're using these objects, don't dispose. Once done, dispose of them. Instead of wrapping them in a using statement, you can always explicitly call Dispose once you're done. Either way the consuming code doesn't need to have any knowledge underlying http requests.

这篇关于何时或是否在调用 ReadAsStreamAsync 时处理 HttpResponseMessage?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:从流创建 Zip 文件并下载 下一篇:循环直到 TcpClient 响应完全读取

相关文章

最新文章