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

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

问题描述

System.Net.Http.HttpClient System.Net.Http.HttpClientHandler 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).

使用语句文档说:

通常,当您使用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();
}

但是Microsoft最明显的例子并不称 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实例执行dispose
操作。我已经在应用程序上使用了using语句来使用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?

他的回答是:


通常,这是正确的,尽管您必须小心
using和async,因为它们并没有真正混入.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.

Btw,您可以多次重复使用同一个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.

(更新:实际上第二段是

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

所以我的问题是:


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

  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.

如果没有必要,

如果有必要(或建议使用),则是上面提到的这段代码可以安全地实现(对于.NET Framework 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.

我也强烈建议您阅读 使用ASP.NET设计可演化的Web API ,以了解幕后情况,特别是此处引用的生命周期部分:

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的标准用法是不要在每次请求后都将其丢弃
。只要您的应用程序需要发出HTTP请求,HttpClient对象就可以生存
。在多个请求中都存在一个对象
可以放置
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天全站免登陆