为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用 HttpClient 处理数据提供者实例?

如何使用 HttpClient 处理数据提供者实例?

C#
ITMISS 2023-12-17 10:20:03
我已经使用存储库模式创建了我的数据提供程序。首先,我设计了一个基础存储库接口,如下所示: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 应用程序,并在类级别定义了存储库,如下所示:IOrderRepository _orderRepository = new OrderRepository();这会影响 Dispose,但却是反模式。我在实现中缺少什么,即每次调用时都没有释放该实例?
查看完整描述

2 回答

?
慕莱坞森

TA贡献1810条经验 获得超4个赞

您不应该在每次请求后都处理 HTTPClient。

因此,HttpClient旨在实例化一次并重用 在应用程序的整个生命周期中。实例化 HttpClient 每个请求的类都会耗尽可用套接字的数量 在重负载下。该问题将导致 SocketException 错误。 解决该问题的可能方法基于创建 HttpClient 对象作为单例或静态,如此处所述 Microsoft 关于 HttpClient 使用的文章。


查看完整回答
反对 回复 2023-12-17
?
跃然一笑

TA贡献1826条经验 获得超6个赞

在通用存储库中编写 Dispose 方法并不意味着它会在您认为需要时自动调用。它旨在单独调用,因此您必须使用using语句(就像您有所示),或代码中的 Dispose 方法。

或者,您可以将该工作留给垃圾收集器。

如果您确信使用,您还应该在通用存储库中创建一个终结器GC.SuppressFinalize(this);

您还应该创建一个静态类来保存 HttpClient。您必须使用 HttpResponseMessages 来满足您的需求,或者 HttpContent。


查看完整回答
反对 回复 2023-12-17
  • 2 回答
  • 0 关注
  • 122 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信