问题描述
我是用的做一些客户端的HTTP通讯。我已经得到了所有的HTTP的在一个地方,从的code,其余抽象化了。在一个实例中欲读取响应内容作为流,但该流的消费者是从哪里HTTP通信发生和该流被打开良好绝缘。在负责HTTP通讯,我处理所有的HTTP客户端的东西的地方。
这个单元测试将会失败 Assert.IsTrue(stream.CanRead)
:
[TestMethod的]
公共异步任务DebugStreamedContent()
{
流流= NULL; //在现实生活中的流的消费者是远
VAR的客户=新的HttpClient();
client.BaseAddress =新的URI(https://www.google.com/,UriKind.Absolute);
使用(VAR要求=新的Htt prequestMessage(HttpMethod.Get,/))
使用(VAR响应=等待client.SendAsync(要求))
{
response.EnsureSuccessStatus code();
//这里我将返回流给调用者
流=等待response.Content.ReadAsStreamAsync();
}
Assert.IsTrue(stream.CanRead); //失败,如果响应设置成是流
}
我通常会尝试尽早方便的,但是在这种情况下,处置的IDisposable
的东西,处置的Htt presponseMessage
还部署了从 ReadAsStreamAsync
。
流
返回所以它看起来像调用code需要了解并采取响应消息的所有权,以及流,或者我离开响应消息未予处置,让与它的终结处理。无论是选择感觉不错。
This回答有关未处置的的HttpClient
会谈。如何在的Htt prequestMessage
和/或的Htt presponseMessage
?
我缺少的东西?我希望能保持消费code无知的Http,但离开这些未予处置对象周围违背习惯的一年!
在这种特定的情况下,的没有终结的。无论是的Htt presponseMessage
或的Htt prequestMessage
实现析构函数(这是一件好事!)。如果你不处理其中任何一个,他们会得到垃圾收集一次在GC踢,和手柄的底层数据流将被全部销毁一旦出现这种情况。
AS @PeterDuniho在评论中说,只要你使用这些对象,不处理。一旦这样做,处置。相反,他们包裹在一个使用
语句,你总是可以显式调用处置
一旦你完成。无论哪种方式消费code不需要有任何的知识基本的HTTP请求。
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 Http client stuff.
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
}
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.
This answer talks about not disposing the HttpClient
. How about the HttpRequestMessage
and/or HttpResponseMessage
?
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!
In this specific case, there are no finalizers. Neither HttpResponseMessage
or HttpRequestMessage
implement a destructor (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 disposed once that happens.
AS @PeterDuniho said in the comments, 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时处置的Htt presponseMessage?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!