![](/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.