HttpClient 和 HttpClientHandler 是否必须在请求之间进行处理? [英] Do HttpClient and HttpClientHandler have to be disposed between requests?

查看:27
本文介绍了HttpClient 和 HttpClientHandler 是否必须在请求之间进行处理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

System.Net.Http.HttpClient and System.Net.Http.HttpClientHandler in .NET Framework 4.5 implement IDisposable (via System.Net.Http.HttpMessageInvoker).

using 声明文档说:

作为规则,当您使用 IDisposable 对象时,您应该声明并在 using 语句中实例化它.

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

这个答案使用这种模式:

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();
}

但是微软最明显的例子没有显式或隐式调用 Dispose().例如:

But the most visible examples from Microsoft don't call Dispose() either explicitly or implicitly. For instance:

  • The original blog article announcing the relase of HttpClient.
  • The actual MSDN documentation for HttpClient.
  • BingTranslateSample
  • GoogleMapsSample
  • WorldBankSample

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

In the announcement's comments, someone asked the Microsoft employee:

检查您的样品后,我发现您没有执行处理HttpClient 实例上的操作.我已经使用了 HttpClient 的所有实例在我的应用程序上使用声明,我认为这是正确的方法因为 HttpClient 实现了 IDisposable 接口.我在正确的路径?

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?

他的回答是:

总的来说这是正确的,尽管你必须小心使用"和异步,因为它们并没有真正混入 .Net 4,在 .Net 4.5 中你可以在using"语句中使用await".

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.

顺便说一句,您可以根据自己的喜好重复使用相同的 HttpClient 多次通常,您不会一直创建/处置它们.

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实例可以使用多少次,而是在你不再需要它之后是否需要处置它.

The second paragraph is superfluous to this question, which is not concerned about how many times you can use an HttpClient instance, but about if it is necessary to dispose it after you no longer need it.

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

(Update: in fact that second paragraph is the key to the answer, as provided below by @DPeden.)

所以我的问题是:

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

  1. Is it necessary, given the current implementation (.NET Framework 4.5), to call Dispose() on HttpClient and HttpClientHandler instances? Clarification: by "necessary" I mean if there are any negative consequences for not disposing, such as resource leakage or data corruption risks.

如果没有必要,既然他们实现了 IDisposable,那么这会是一个好的做法"吗?

If it's not necessary, would it be a "good practice" anyway, since they implement IDisposable?

如果有必要(或推荐),上面提到的这段代码是安全实现的(对于 .NET框架 4.5)?

If it's necessary (or recommended), is this code mentioned above implementing it safely (for .NET Framework 4.5)?

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

If these classes don't require calling Dispose(), why were they implemented as IDisposable?

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

If they require, or if it's a recommended practice, are the Microsoft examples misleading or unsafe?

推荐答案

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

The general consensus is that you do not (should not) need to dispose of HttpClient.

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

Many people who are intimately involved in the way it works have stated this.

请参阅Darrel Miller 的博文 和相关的SO帖子:HttpClient爬取导致内存泄漏供参考.

See Darrel Miller's blog post and a related SO post: HttpClient crawling results in memory leak for reference.

我还强烈建议您阅读 Designing Evolvable Web APIs with ASP.NET 中的 HttpClient 章节,了解幕后发生的事情的上下文,特别是引用的生命周期"部分这里:

I'd also strongly suggest that you read the HttpClient chapter from Designing Evolvable Web APIs with ASP.NET for context on what is going on under the hood, particularly the "Lifecycle" section quoted here:

虽然 HttpClient 确实间接实现了 IDisposable接口,HttpClient的标准用法是不去dispose在每次请求之后.HttpClient 对象旨在作为只要您的应用程序需要发出 HTTP 请求.有对象存在于多个请求中,可以设置一个地方DefaultRequestHeaders 并防止您重新指定每个请求上的 CredentialCache 和 CookieContainer 之类的东西HttpWebRequest 是必需的.

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.

Or even open up DotPeek.

这篇关于HttpClient 和 HttpClientHandler 是否必须在请求之间进行处理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆