当我为每个请求创建实例时,是否应该在 C# 中处理 HttpClient?

问题描述 投票:0回答:1

有许多资源要求重新使用

HttpClient
实例以避免套接字耗尽。在这种方法中,不应处置
HttpClient
实例。

但类似于this答案中第一条评论中的问题:

“如果您保留该实例以供稍后重用,则无需处置

HttpClient
”这样说是否正确?例如,如果重复调用一个方法并创建一个新的
HttpClient
实例(即使在大多数情况下这不是推荐的模式),那么说该方法不应该处置该实例(不会被重用)是否仍然正确? )?这可能会导致数千个未处理的实例。

我想知道是否应该在不遵循模式的应用程序中使用

using
关键字进行处理,并为每个请求创建实例。

请不要建议更改设计以重复使用,因为这将在适当的时候完成,但请建议在每个请求发生创建时的正确使用方法。

对于点网核心。

c# .net .net-core dotnet-httpclient
1个回答
0
投票

每当您将

using
用于
HttpClient
实例时,都会发生以下情况:

  • HttpClient
    通过
    CancellationToken
    取消所有待处理的请求。 参考
  • HttpMessageInvoker
    HttpClient
    的基类)处理底层的
    HttpMessageHandler
    参考
    • HttpMessageHandler
      是一个抽象类,有很多实现类如
      SocketsHttpHandler
      HttpClientHandler
      等。Ref
    • 每当您分配新的
      HttpClient
      时,您都会使用
      HttpClientHandler
      参考
  • HttpClientHandler
    处置其底层
    HttpHandlerType
    参考
    • 它是
      BrowserHttpHandler
      SocketsHttpHandler
      参考
  • SocketsHttpHandler
    处置其底层
    HttpMessageHandlerStage
    参考
    • 此阶段对象保存处理程序链的引用。
    • 根据您的设置,链可能包含非常不同的处理程序
    • 最里面的处理程序是
      HttpAuthenticatedConnectionHandler
      HttpConnectionHandler
  • 在这两种连接处理程序情况下,它们都会处置其
    HttpConnectionPoolManager
    Ref
  • HttpConnectionPoolManager
    处理多个计时器,
    HttpConnectionPool
    Ref 并取消订阅
    NetworkChange.NetworkAddressChanged
    事件 Ref
  • HttpConnectionPool
    进行了大量的清理工作,并且它可以识别 HTTP 协议版本。 参考
  • ...

我停在这里,因为以下原因:

  • SocketsHttpClientHandler
    是您可以直接交互的最低
    public
    类。所有较低层都是
    internal
    ,所以它们只是实现细节。
  • 正如您所看到的,
    HttpClient
    dispose chain不仅仅是简单地取消待处理的请求,它还做了很多事情。

因此,在使用完

HttpClient
之后清理东西是一个更好的选择,恕我直言,然后等待GC在触发时为你做这件事。

© www.soinside.com 2019 - 2024. All rights reserved.