c# - 是否必须在请求之间处理 HttpClient 和 HttpClientHandler?

标签 c# .net-4.5 idisposable using dotnet-httpclient

System.Net.Http.HttpClientSystem.Net.Http.HttpClientHandler在 .NET Framework 4.5 中实现 IDisposable(通过 System.Net.Http.HttpMessageInvoker )。

using 语句文档说:

As a rule, when you use an IDisposable object, you should declare and instantiate it in a using statement.

This answer使用这种模式:

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()。例如:

announcement的评论,有人问微软员工:

After checking your samples, I saw that you didn't perform the dispose action on HttpClient instance. I have used all instances of HttpClient with using statement on my app and I thought that it is the right way since HttpClient implements the IDisposable interface. Am I on the right path?

他的回答是:

In general that is correct although you have to be careful with "using" and async as they dont' really mix in .Net 4, In .Net 4.5 you can use "await" inside a "using" statement.

Btw, you can reuse the same HttpClient as many times are [as] you like so typically you won't create/dispose them all the time.

第二段对于这个问题来说是多余的,这个问题不关心你可以使用多少次 HttpClient 实例,而是关心在你不再需要它之后是否有必要处置它。

(更新:事实上,第二段是答案的关键,如下由@DPeden 提供。)

所以我的问题是:

  1. 鉴于当前的实现 (.NET Framework 4.5),是否有必要在 HttpClient 和 HttpClientHandler 实例上调用 Dispose()?澄清:“必要”是指如果不处置会产生任何负面后果,例如资源泄漏或数据损坏风险。

  2. 如果没有必要,这会是一个“好的做法”吗,因为他们实现了 IDisposable?

  3. 如果有必要(或推荐),是 this code上面提到安全地实现它(对于 .NET Framework 4.5)?

  4. 如果这些类不需要调用 Dispose(),为什么将它们实现为 IDisposable?

  5. 如果他们需要,或者如果这是推荐的做法,Microsoft 示例是否具有误导性或不安全?

最佳答案

普遍的共识是您不需要(不应该)处理 HttpClient。

许多密切参与其工作方式的人都说过这一点。

参见 Darrel Miller's blog post和相关的 SO 帖子:HttpClient crawling results in memory leak供引用。

我还强烈建议您阅读 the HttpClient chapter from Designing Evolvable Web APIs with ASP.NET有关引擎盖下发生的事情的上下文,特别是此处引用的“生命周期”部分:

Although HttpClient does indirectly implement the IDisposable interface, the standard usage of HttpClient is not to dispose of it after every request. The HttpClient object is intended to live for as long as your application needs to make HTTP requests. Having an object exist across multiple requests enables a place for setting DefaultRequestHeaders and prevents you from having to re-specify things like CredentialCache and CookieContainer on every request as was necessary with HttpWebRequest.

甚至打开 DotPeek。

关于c# - 是否必须在请求之间处理 HttpClient 和 HttpClientHandler?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15705092/

相关文章:

c# - 为什么在 Plain TextBox 中显示多种字体大小?

c# - 参数化查询需要未提供的参数 p1

c# - Html.DropDownList 从列表中选择值<string>

c# - 使用 java 和 WP7 进行 AES 加密

c# - 如何查看 Redis-Commands RESP 表示

c# - 通过引用传递 IDisposable 对象会导致错误?

c# - 当它们的字段实现 IDisposable 时,我该如何处理我的 Controller ?

C# Linq OrderBy 过滤 null 或空值到最后

c# - 等待某事发生——异步或同步模型?

.net - 为什么即使我不调用服务的 Dispose() 方法也会调用它? (使用 BasicHttpBinding)