.NET Framework 4.5中的System.Net.Http.HttpClient和System.Net.Http.HttpClientHandler实现IDisposable(通过System.Net.Http.HttpMessageInvoker)。
该using
声明文件说:
通常,使用IDisposable对象时,应在using语句中声明并实例化它。
此答案使用以下模式:
var baseAddress = new Uri("http://example.com");
var cookieContainer = new CookieContainer();
using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer })
using (var client = new HttpClient(handler) { BaseAddress = baseAddress })
{
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("foo", "bar"),
new KeyValuePair<string, string>("baz", "bazinga"),
});
cookieContainer.Add(baseAddress, new Cookie("CookieName", "cookie_value"));
var result = client.PostAsync("/test", content).Result;
result.EnsureSuccessStatusCode();
}
但是Microsoft最明显的示例都没有Dispose()
显式或隐式调用。例如:
- 在原来的博客文章中宣布的HttpClient的RELASE。
- HttpClient 的实际MSDN文档。
- BingTranslateSample
- GoogleMapsSample
- 世界银行样本
在公告的评论中,有人问微软员工:
检查样本后,我发现您没有对HttpClient实例执行dispose操作。我已经在应用程序上使用了using语句来使用HttpClient的所有实例,并且我认为这是自HttpClient实现IDisposable接口以来的正确方法。我在正确的道路上吗?
他的回答是:
通常,这是正确的,尽管您必须谨慎使用“使用”和异步,因为它们并没有真正混入.Net 4中。在.Net 4.5中,您可以在“ using”语句中使用“ await”。
顺便说一句,您可以根据自己的喜好重复使用相同的HttpClient多次,因此通常您不会一直创建/处置它们。
第二段对于该问题是多余的,它不关心您可以使用HttpClient实例多少次,而是关心在不再需要它之后是否有必要处置它。
(更新:实际上,第二段是答案的关键,如@DPeden所提供。)
所以我的问题是:
在当前实现(.NET Framework 4.5)的情况下,是否有必要在HttpClient和HttpClientHandler实例上调用Dispose()?澄清:“必要”是指是否存在不处置的任何负面后果,例如资源泄漏或数据损坏风险。
如果没有必要,因为它们实现了IDisposable,这是否仍然是“良好实践”?
如果有必要(或建议),上述代码是否可以安全地实现(对于.NET Framework 4.5)?
如果这些类不需要调用Dispose(),为什么将它们实现为IDisposable?
如果他们有要求,或者这是推荐做法,那么Microsoft示例是否具有误导性或不安全性?
Flush
在每次写操作之后调用一次,除了不便继续将基础资源保留超过必要的时间之外,“正确的行为”将不会发生什么?