[英]How to dispose the data provider instance using HttpClient?
我已經使用存儲庫模式創建了我的數據提供者。
首先,我設計了一個基本存儲庫接口,如下所示:
internal interface IGenericRepository<T, in TResourceIdentifier>
{
Task<IEnumerable<T>> GetManyAsync();
Task<T> GetAsync(TResourceIdentifier id);
Task PutAsync(T model);
Task<T> PostAsync(T model);
Task DeleteAsync(TResourceIdentifier id);
}
然后我實現了它:
public class GenericRepository<T, TResourceIdentifier> : IDisposable, IGenericRepository<T, TResourceIdentifier>
where T : class
{
private bool _disposed;
protected HttpClientHelper<T, TResourceIdentifier> Client;
protected GenericRepository(string addressSuffix)
{
Client = new HttpClientHelper<T, TResourceIdentifier>(Properties.Settings.Url, addressSuffix);
}
public async Task<IEnumerable<T>> GetManyAsync()
{
return await Client.GetManyAsync();
}
// All other CRUD methods and dispose
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if(_disposed || !disposing) return;
if(Client != null)
{
var mc = Client;
Client = null;
mc.Dispose();
}
_disposed = true;
}
}
然后我為我的每個實體創建了自定義存儲庫接口。 例如:
internal interface IOrderRepository : IGenericRepository<Order, int>
{
Task<IEnumerable<Order>> GetOrderBySomeConditionAsync(string condition );
}
最后,我實現了自定義存儲庫:
public class OrderRepository : GenericRepository<Order, int>, IOrderRepository
{
public OrderRepository(string addressSuffix) : base(addressSuffix)
{
}
public async Task<IEnumerable<Order>> GetOrderBySomeConditionAsync(string condition)
{
//get all the orders (GetManyAsync()) and then returns the ones meeting the condition
}
}
注意HttpClientHelper
使用HttpClient
,需要手動處理。
我創建了一個 MVC web 應用程序,並在 class 級別定義了存儲庫,如下所示:
IOrderRepository _orderRepository = new OrderRepository();
當我在 CRUD 操作中調用_orderRepository
時,它在使用后不會命中 dispose。 為了解決這個問題,我最終實現了這樣的:
private async Task<IEnumerable<OrderViewModel>> GetOrders()
{
using(var orderRepository = new OrderRepository())
return await orderRepository.GetManyAsync();
}
這會擊中 Dispose 但是反模式。
我在我的實現中缺少什么實例沒有在每次調用時處理?
您不應該在每次請求后處理 HTTPClient。
正如上面的鏈接所說 -
因此,HttpClient 旨在被實例化一次並在應用程序的整個生命周期中重用。 為每個請求實例化一個 HttpClient class 將耗盡重負載下可用的 sockets 的數量。 該問題將導致 SocketException 錯誤。 解決該問題的可能方法是基於將 HttpClient object 創建為 singleton 或 static,如這篇關於 HttpClient 使用的 Microsoft 文章中所述。
在您的通用存儲庫中編寫 Dispose 方法並不意味着它會在您覺得應該時自動調用。 它旨在單獨調用,因此您必須使用using
語句(如您所示)或代碼中的Dispose
方法。
或者,您可以將該工作留給垃圾收集器。
如果您確信使用GC.SuppressFinalize(this);
在此處閱讀更多相關信息 - 我應該何時使用 GC.SuppressFinalize()?
正如R Jain指出的那樣,您還應該創建一個 static class 來保存您的 HttpClient。 您必須根據需要使用 HttpResponseMessages 或 HttpContent。
更多閱讀資源:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.