根据 Microsoft 的指南,我希望通过仅拥有 HttpClient
pr 的单个实例来确保正确使用 HttpClient
。 API 消耗。我对我的解决方案能否正常工作感到有点厌倦
我尝试在创建函数周围添加一个锁,如果静态变量为空,该函数就会被调用。
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
只为每个类实例化一次,这样我就不会在套接字的使用中溢出。这段代码能保证这种情况发生吗?
最佳答案
确保只有一个 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 在那里解决了问题。
关于c# - 如何确保我的 HttpClient 在 C# 中只初始化一次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57803789/