根据Microsoft的指南,我想通过仅拥有HttpClient
公关的一个实例来确保正确使用HttpClient
。 API已消耗。我对我的解决方案正常工作感到有些疲倦
我尝试在创建函数周围添加锁,如果静态变量为null,则会调用该函数。
public class BaseClient
{
private static volatile HttpClient _httpClient;
private static readonly object HttpClientLock = new object();
public BaseClient(string serviceAddress, string apiKeyRequestHeader, string apiKeyValue)
{
CreateClient(serviceAddress, apiKeyValue, apiKeyRequestHeader);
}
private void CreateClient(string baseAddress, string apiKeyRequestHeaderValue, string apiKeyRequestHeader)
{
if (_httpClient == null)
{
lock (HttpClientLock)
{
if (_httpClient == null)
{
_httpClient = new HttpClient
{
BaseAddress = new Uri(baseAddress)
};
_httpClient.DefaultRequestHeaders.Accept.Add(
MediaTypeWithQualityHeaderValue.Parse("application/json"));
if (!string.IsNullOrEmpty(apiKeyRequestHeaderValue))
_httpClient.DefaultRequestHeaders.Add(apiKeyRequestHeader, apiKeyRequestHeaderValue);
_httpClient.Timeout = new TimeSpan(0, 3, 0);
}
}
}
}
}
我想确保HttpClient
对于每个类都只实例化一次,因此在使用套接字时不会溢出。这段代码可以保证发生这种情况吗?
答案 0 :(得分:3)
确保HttpClient
只有一个实例的最简单方法是利用静态初始化(默认情况下是线程安全的)(由框架保证),该静态初始化在post中有关于C#中可能的单例实现。
在此示例之后,您可以通过避免锁定来简化代码:
public class BaseClient
{
private static readonly HttpClient _httpClient = new HttpClient();
static BaseClient()
{
}
public BaseClient(string serviceAddress, string apiKeyRequestHeader, string apiKeyValue)
{
InitializeClient(serviceAddress, apiKeyValue, apiKeyRequestHeader);
}
private void InitializeClient(string baseAddress, string apiKeyRequestHeaderValue, string apiKeyRequestHeader)
{
_httpClient.BaseAddress = new Uri(baseAddress);
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
_httpClient.Timeout = TimeSpan.FromMinutes(3);
if (!string.IsNullOrEmpty(apiKeyRequestHeaderValue))
{
_httpClient.DefaultRequestHeaders.Add(apiKeyRequestHeader, apiKeyRequestHeaderValue);
}
}
}
除此之外,您始终可以测试方法并检查一次是否可以有多个实例。
注意:
当DNS changes时,拥有一个HttpClient实例可能会导致问题。如果您使用的是.Net Core,则应改用HttpClientFactory
,因为Microsoft在那里对问题进行了排序。