.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 实例上执行 dispose 操作。我已经在我的应用程序中使用了所有 HttpClient 实例,并且认为这是正确的方式,因为 HttpClient 实现了 IDisposable 接口。我走上了正确的道路吗?
他的回答是:
通常情况下是正确的,虽然您必须小心 "using" 和 async 的混合使用,在 .NET 4 中它们不能真正地混合使用。在 .NET 4.5 中,您可以在 "using" 语句中使用 "await"。
顺便说一下,您可以重复使用相同的 HttpClient,所以通常不需要创建/处理它们所有的时间。
第二段对于这个问题来说是多余的,因为这个问题并不关心您可以使用 HttpClient 实例的次数,而是关于在您不再需要它时是否需要释放它。
(更新:实际上,正如 @DPeden 提供的答案所述,第二段是答案的关键。)
所以我的问题是:
根据当前的实现 (.NET Framework 4.5),是否需要调用 HttpClient 和 HttpClientHandler 实例的 Dispose() 方法?澄清一下:我所说的 "需要" 是指没有释放会导致任何负面影响,例如资源泄漏或数据损坏风险。
如果不需要,在实现 IDisposable 的情况下,是否仍然是“良好的实践”?
如果需要(或推荐),上面提到的 代码 是否安全实现了它 (对于 .NET Framework 4.5)?
如果这些类不需要调用 Dispose(),为什么还要实现 IDisposable 接口?
如果它们需要,或者如果这是一种推荐实践,请问微软的示例是否具有误导性或不安全?
Flush
,除了它持续保持底层资源比必要时间长的不便之外,还需要发生什么才能实现“正确的行为”? - Damien_The_Unbeliever