Dot-Net-Core

由 HttpClientFactory 創建的 HttpClient 實例是否應該被釋放?

  • June 18, 2018

因此,我在 Startup.cs 中使用服務集合註冊了一個命名客戶端:

services.AddHttpClient(someServiceName, 
                      client => client.BaseAddress = baseAddress);

現在可以IHttpClientFactory從我的服務提供商那裡註入一個。

使用這個IHttpClientFactory,我想出了一個客戶端實例:

var client = httpClientFactory.CreateClient(someServiceName)

曾幾何時,在處理HttpClient實例時必須非常小心,因為這很少是正確的做法

但是,現在我們有了HttpClientFactory,這還重要嗎?應該/可以client放心地處理嗎?例如

using (var httpClient = httpClientFactory.CreateClient(someServiceName))
using (var response = await httpClient.PostAsync(somePath, someData))
{
   var content = await response.Content.ReadAsAsync<SomeResponse>();
   //...
}

不需要呼叫該Dispose方法,但如果出於某些原因需要,您仍然可以呼叫它。

證明:HttpClient 和生命週期管理

不需要處理客戶端。Disposal 取消傳出請求並保證在呼叫 Dispose 後不能使用給定的 HttpClient 實例。IHttpClientFactory 跟踪和釋放 HttpClient 實例使用的資源。HttpClient 實例通常可以被視為不需要處置的 .NET 對象。

檢查來源DefaultHttpClientFactory

public HttpClient CreateClient(string name)
{
   if (name == null)
   {
       throw new ArgumentNullException(nameof(name));
   }

   var handler = CreateHandler(name);
   var client = new HttpClient(handler, disposeHandler: false);

   var options = _optionsMonitor.Get(name);
   for (var i = 0; i < options.HttpClientActions.Count; i++)
   {
       options.HttpClientActions[i](client);
   }

   return client;
}

的實例HttpMessageHandler儲存 的非託管資源HttpClient。在經典場景中,HttpClient創建實例HttpMessageHandler並在自己處理時處理它。

您可以在上面的程式碼中看到,不同的實例HttpClient共享單個實例HttpMessageHandler並且不釋放它(disposeHandler: false)。

所以,呼叫 theHttpClient.Dispose什麼都不做。但這並不危險。

不,您不應該處置您的客戶。更一般地說,您不應該處理通過 DI 容器檢索到的任何內容,在 ASP.NET Core 中,預設情況下該容器是服務集合。生命週期由 DI 容器管理,因此如果您處置客戶端,但稍後將其註入某些東西,您將獲得一個ObjectDisposedException. 讓容器處理處置。

這實際上是與IDisposable類的常見混淆。IDisposable只有當您的類本身擁有依賴項時,您才應該親自實現。如果它的所有依賴項都被注入,你不應該實現IDisposable,因為它不擁有任何需要處理的東西。同樣,您不應該處理注入到您的類中的任何東西,因為它不擁有這些依賴項。只處理你特別新的東西。如果您沒有看到關鍵字new,您可能不應該處理。

引用自:https://stackoverflow.com/questions/50912160