![](/img/trans.png)
[英]AddHttpClient<TClient> with just an interface class?
[英]AddHttpClient<TClient,TImplementation> registers as transient, can it handle high volume concurrent requests efficiently?
我注意到在使用 ASP.NET Core 的IHttpClientFactory
时,类型化客户端注册方法AddHttpClient<TClient,TImplementation>
做了两件事:
它将<TClient,TImplementation>
的 DI 注册为瞬态,就像在 startup.cs 中调用services.AddTransient<TClient,TImplementation>
它将为每个启动的 object 注入此注册类型的HttpClient
实例。
我担心的是,如果将其配置为瞬态,它是否能够处理大量并发的TImplementation
对象进行 http 调用,因为每次调用都会创建一个新的HttpClient
和一个新的TClient
? 这些客户端都将访问相同的 URL,sockets 会被正确重用吗?
正如King King已经指出重要的HttpMessageHandler
。
为了更好地理解它是如何工作的,我建议检查DefaultHttpClientFactory
的源代码。
我们来看看CreateClient方法:
public HttpClient CreateClient(string name)
{
if (name == null)
{
throw new ArgumentNullException(nameof(name));
}
HttpMessageHandler handler = CreateHandler(name);
var client = new HttpClient(handler, disposeHandler: false);
HttpClientFactoryOptions options = _optionsMonitor.Get(name);
for (int i = 0; i < options.HttpClientActions.Count; i++)
{
options.HttpClientActions[i](client);
}
return client;
}
如您所见,它调用CreateHandler :
public HttpMessageHandler CreateHandler(string name)
{
if (name == null)
{
throw new ArgumentNullException(nameof(name));
}
ActiveHandlerTrackingEntry entry = _activeHandlers.GetOrAdd(name, _entryFactory).Value;
StartHandlerEntryTimer(entry);
return entry.Handler;
}
在这里,我们通过_activeHandlers
有一个处理程序池。 还有一个工厂方法_entryFactory
,当给定条目不存在时调用。 让我们看一下它们的定义:
_activeHandlers = new ConcurrentDictionary<string, Lazy<ActiveHandlerTrackingEntry>>(StringComparer.Ordinal);
_entryFactory = (name) =>
{
return new Lazy<ActiveHandlerTrackingEntry>(() =>
{
return CreateHandlerEntry(name);
}, LazyThreadSafetyMode.ExecutionAndPublication);
};
_expiredHandlers = new ConcurrentQueue<ExpiredHandlerTrackingEntry>();
因此,如您所见,它使用Lazy
结构来最小化初始化成本。
相关的CreateHandlerEntry
的源代码可以在这里找到,如果你有兴趣的话。
我还建议阅读Stephen Gordon 关于这个主题的优秀文章。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.