不要HttpClient的和HttpClientHandler必须处理? [英] Do HttpClient and HttpClientHandler have to be disposed?

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

问题描述

System.Net.Http.HttpClient 和<一个href=\"http://msdn.microsoft.com/en-us/library/system.net.http.httpclienthandler.aspx\">System.Net.Http.HttpClientHandler在.NET框架4.5实现IDisposable(通过<一个href=\"http://msdn.microsoft.com/en-us/library/system.net.http.httpmessageinvoker.aspx\">System.Net.Http.HttpMessageInvoker).

使用语句文件说:


  

作为一个规则,当您使用IDisposable的对象,还应当声明并
  实例在一个using语句。


这个答案使用此模式:

  VAR baseAddress =新的URI(http://example.com);
VAR的CookieContainer =新的CookieContainer();
使用(VAR处理器=新HttpClientHandler(){=的CookieContainer}的CookieContainer)
使用(VAR的客户=新的HttpClient(处理){BaseAddress = baseAddress})
{
    VAR内容=新FormUrlEn codedContent(新[]
    {
        新KeyValuePair&LT;字符串,字符串&GT;(富,酒吧),
        新KeyValuePair&LT;字符串,字符串&GT;(巴兹,bazinga),
    });
    cookieContainer.Add(baseAddress,新的Cookie(CookieName,cookie_value));
    VAR的结果= client.PostAsync(/测试,内容)。结果;
    result.EnsureSuccessStatus code();
}

不过从微软最明显的例子不叫的Dispose()或隐或显。例如:

公布的意见,有人问微软员工:


  

检查你的样品后,我看到你没有执行的Dispose
  在HttpClient的实例行动。我用的HttpClient的所有实例
  用我的应用程序声明,我认为这是正确的方式
  由于HttpClient的实现IDisposable接口。我是在
  正确的道路?


他的回答是:


  

在普遍认为是正确的,虽然你必须要小心
  使用和异步,因为他们不'真的混在.NET 4中,在.NET 4.5,你
  可以用等待里面的使用的声明。


  
  

顺便说一句,你可以重复使用相同的HttpClient多次为[因为]你喜欢这样
  通常你会不会创建/处理他们所有的时间。


第二段是superflous这个问题,这是不关心你有多少次使用HttpClient的实例,但如果有必要处置后,你不再需要它。

(更新:事实上这第二段是关键答案,如低于@DPeden提供)

所以我的问题是:


  1. 是否有必要,因为当前的实现(.NET框架4.5),对HttpClient的和HttpClientHandler实例调用Dispose()?澄清:由必要的我的意思是,如果有不处理,如资源泄漏或数据损坏的风险的任何负面影响,


  2. 如果这不是必要的,这将是一个良好做法无论如何,因为他们实现IDisposable?


  3. 如果有必要(或建议),是上面安全地实现它提到了这个code (用于.NET Framework 4.5)?


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


  5. 如果他们需要,或者如果它是一个推荐的做法,是微软的例子误导或不安全?



解决方案

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

谁是密切参与工作的方式很多人都表示这一点。

请参阅达雷尔 - 米勒的博客文章和相关SO岗位:<一href=\"http://stackoverflow.com/questions/14075026/httpclient-crawling-results-in-memory-leak\">HttpClient在内存抓取结果泄露,以供参考。

我也强烈建议您阅读 HttpClient的章节,从设计与演化的Web API的ASP.NET 以对什么是引擎盖下回事,特别是生命周期一节在这里引述方面:


  

虽然HttpClient的不间接实现IDisposable
  接口HttpClient的标准用法是不处理它
  之后每个请求。 HttpClient的对象是为了活的
  只要你的应用程序需要进行HTTP请求。具有对象
  在多个请求存在使设置的地方
  不必DefaultRequestHeaders和prevents您重新指定
  之类的东西CredentialCache和的CookieContainer作为每个请求
  必须用HttpWebRequest的。


甚至开辟DotPeek。

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

The using statement documentation says:

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

This answer uses this pattern:

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

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

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

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?

His answer was:

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.

The second paragraph is superflous to this question, which is not concerned about how many times you can use an HttpClient instance, but if it 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.)

So my questions are:

  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.

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

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

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

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

解决方案

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.

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

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:

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.

Or even open up DotPeek.

这篇关于不要HttpClient的和HttpClientHandler必须处理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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