我们可以在这里阅读到你正在错误地使用HttpClient,并且它正在破坏你的软件,我们不应该为每个http请求创建和释放HttpClient。相反,它应该被缓存和重用(例如作为DI容器中的单例)。同样,在官方的.NET文档中也提到了HttpClient:
每次调用都会创建一个HttpClient实例,并且调用者可以缓存它。
每次调用IHttpClientFactory.CreateClient都保证返回一个新的HttpClient实例。调用者可以无限期地缓存返回的实例,或者在需要时将其包装在using块中以进行释放。
所以问题是,我应该完全依赖HttpClientFactory还是仍然应该缓存从中创建的HttpClient?
在我们的项目中,每次发出请求时我们都使用HttpClientFactory.CreateClient,但仍然会出现套接字异常。
建议使用HttpClientFactory,但在查看了之后,HttpClient应该在应用程序的整个生命周期中只被实例化一次并重复使用。在每个请求中实例化一个HttpClient类将在高负载下耗尽可用的套接字数量。这将导致SocketException错误。下面是一个正确使用HttpClient的示例。
public interface IHttpClientFactory
{
/// <summary>
/// Creates and configures an <see cref="T:System.Net.Http.HttpClient" /> instance using the configuration that corresponds
/// to the logical name specified by <paramref name="name" />.
/// </summary>
/// <param name="name">The logical name of the client to create.</param>
/// <returns>A new <see cref="T:System.Net.Http.HttpClient" /> instance.</returns>
/// <remarks>
/// <para>
/// Each call to <see cref="M:System.Net.Http.IHttpClientFactory.CreateClient(System.String)" /> is guaranteed to return a new <see cref="T:System.Net.Http.HttpClient" />
/// instance. Callers may cache the returned <see cref="T:System.Net.Http.HttpClient" /> instance indefinitely or surround
/// its use in a <langword>using</langword> block to dispose it when desired.
/// </para>
/// <para>
/// The default <see cref="T:System.Net.Http.IHttpClientFactory" /> implementation may cache the underlying
/// <see cref="T:System.Net.Http.HttpMessageHandler" /> instances to improve performance.
/// </para>
/// <para>
/// Callers are also free to mutate the returned <see cref="T:System.Net.Http.HttpClient" /> instance's public properties
/// as desired.
/// </para>
/// </remarks>
HttpClient CreateClient(string name);
}
每次调用都会创建一个HttpClient实例,并且调用者可以缓存它。
每次调用IHttpClientFactory.CreateClient都保证返回一个新的HttpClient实例。调用者可以无限期地缓存返回的实例,或者在需要时将其包装在using块中以进行释放。
所以问题是,我应该完全依赖HttpClientFactory还是仍然应该缓存从中创建的HttpClient?
在我们的项目中,每次发出请求时我们都使用HttpClientFactory.CreateClient,但仍然会出现套接字异常。