我们可以在这里YOU'RE USING HTTPCLIENT WRONG AND IT IS DESTABILIZING YOUR SOFTWARE读到,我们不应该为每个http请求创建和处置HttpClient。相反,应该对其进行缓存和重用(例如,作为DI容器中的Singleton)。以及HttpClient的.NET官方文档中:
HttpClient旨在实例化一次,并在应用程序的整个生命周期内重复使用。为每个请求实例化HttpClient类将耗尽繁重负载下可用的套接字数量。这将导致SocketException错误。下面是正确使用HttpClient的示例。
建议使用HttpClientFactory,但在查看之后:
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 实例。调用者可以无限期缓存或环绕返回的实例
所以问题是我应该完全依靠 HttpClientFactory 还是应该缓存从中创建的 HttpClient ?
在我们的项目中,每次发出请求时,我们都会使用 HttpClientFactory.CreateClient ,他仍然会有套接字异常。
答案 0 :(得分:4)
HttpClient
仅是IDisposable
,因为其HttpMessageHandler
是IDisposable
。实际上,HttpMessageHandler
应该是长寿的。
HttpClientFactory
通过在内部保留一个寿命长的HttpMessageHandler
来工作。每当您要求使用HttpClient
时,它都会使用寿命长的HttpMessageHander
,并在HttpClient
被使用时告诉HttpClient
not 进行处置。处置。
您可以看到on GitHub:
public HttpClient CreateClient(string name)
{
// ...
// Get a cached HttpMessageHandler
var handler = CreateHandler(name);
// Give it to a new HttpClient, and tell it not to dispose it
var client = new HttpClient(handler, disposeHandler: false);
// ...
return client;
}
因此,从技术上讲,缓存HttpClient
还是立即处置并不重要-处置它不会做任何事情(因为有人告诉您不要处置其HttpClientHandler
,因为由HttpClientFactory
管理。
关于处置HttpClient
,MSDN says:
不需要处理客户端。 Disposal取消传出的请求,并确保在调用Dispose之后不能使用给定的HttpClient实例。 IHttpClientFactory跟踪并处置HttpClient实例使用的资源。 HttpClient实例通常可以视为不需要处理的.NET对象。
在IHttpClientFactory建立之前,通常使用一个长期的单个HttpClient实例。迁移到IHttpClientFactory后,该模式就不再需要。
我怀疑您看到的SocketException
是有不同的原因。也许问一个针对他们的新问题?
答案 1 :(得分:1)
在 #source file location
path = "myfile.csv"
# define column location and then define the width
column_locations = np.array([1, 25, 30, 31, 47, 58, 75, 92, 109, 126, 132, 152, 158, 163, 179, 190, 207, 224, 241, 258, 264, 295, 311, 322, 356, 373 ])
widths = column_locations[1:] - column_locations[:-1]
#creating numpy array from the source file
data = np.genfromtxt(path, dtype=None, delimiter=widths, autostrip=True)
print(data)
data =np.char.replace(data,',',' ')
np.savetxt(path,data,delimiter=",",fmt='%s')
版本中,情况发生了很大的变化。
ASP.NET Core 2.2
的使用方式仅是通过DI进行的,DI使用HttpClient
在内部为您处理所有必需的缓存。以下文档文章已更新,以反映这些新用例:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-2.2
另外,来自ASP.NET Core团队的@RyanNowak在以下ASP.Net Core社区站立会议中介绍了所有这些更改:https://www.youtube.com/watch?v=Lb12ZtlyMPg 如果您还没有看过,我强烈建议您观看,因为它具有丰富的信息和教育意义。
这里有一个小样本来展示用法。在HttpClientFactory
方法调用中:
Startup.ConfigureServices
注意:存在多种使用模式,这是最基本的一种。在文档中查找其他模式,可以更好地满足您的需求。
稍后,在该类中,您要从其发出http请求,请对services.AddHttpClient();
进行依赖,然后让DI必要时为您实例化它。这是Microsoft Docs的示例:
IHttpClientFactory