处理注入的 HttpClient 对象

4
我们的MVC应用程序使用HttpClient调用WebAPI动作。我决定使用StructureMap注入HttpClient并在控制器中覆盖dispose方法。
public HomeController(HttpClient httpClient)
{
    _httpClient = httpClient;
}

protected override void Dispose(bool disposing)
{
   if (disposing && _httpClient != null)
   {
       _httpClient.Dispose();
   }
   base.Dispose(disposing);
}

StructureMap的ObjectInitialize基本上看起来像这样...
x.For<HttpClient>().Use(() => new HttpClient() { BaseAddress = "my/uri/"});

当我构建这个项目时,CodeAnalysis会抱怨"Dispose objects before losing scope"并指向IoC代码。

我能否忽略这个问题,或者在哪里需要处理HttpClient的Dispose?我也尝试过...

protected void Application_EndRequest(object sender, EventArgs e)
{
    ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
}

但我仍然收到了违规通知。
2个回答

6

释放 HttpClient 会清理所有活动的取消令牌和任何部分完成的请求/响应。在大多数正常情况下,释放它不是必要的,但按照惯例应该这样做。但请注意,释放 HttpClient 将强制关闭 TCP 连接。

如果您的 MVC 应用程序正在对同一服务器进行大量调用,则可能值得跨请求保留 HttpClient 实例并重复使用它。这将避免每次都重新设置默认请求标头,并允许重用 TCP 连接。


3
通常,触发对象创建的对象也应负责其处理。在这种情况下,HttpClient是由Structuremap通过DependencyResolver或ControllerFactory创建的。使用Structuremap没有简单的方法来处理短暂对象,因此您需要最小化注入IDisposable对象的次数,尤其是短暂对象。我认为您应该将创建和处理放在一个服务中,并将其注入到控制器中。
ReleaseAndDisposeAllHttpScopedObjects在这种情况下将不起作用,因为它只处理配置为HttpScoped的对象,即整个http请求期间保留的对象。

有帮助。感谢您的输入。如果我在StructureMap中使用“HttpContextScoped”,那么“ReleaseAndDisposeAllHttpScopedObjects”会起作用吗? - jlembke
1
@jlembke - 是的,使用 HttpContextScoped 后,ReleaseAndDisposeAllHttpScopedObjects 方法将会起作用。 - PHeiberg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接