【发布时间】:2015-06-28 00:49:57
【问题描述】:
我们正在为 HttpClient 创建一个包装器。因为我们将遵循https://github.com/mspnp/performance-optimization 的性能优化指导。我们希望避免反模式 - 该文档中提到的不正确实例化。我将此指南推荐给我的团队以使用静态 HttpClient。我得到的反馈是关于线程安全的。每个请求都有一个包含用户声明的标头。由于我有一个静态 HttpClient,它会是线程安全的吗?如果我们有多个请求同时访问代码(例如 GET),设置标头会是竞争条件吗?我们有如下实现。
public class HttpClientHelper{
private static readonly HttpClient _HttpClient;
static HttpClientHelper() {
HttpClient = new HttpClient();
HttpClient.Timeout = TimeSpan.FromMinutes(SOME_CONFIG_VALUE);
}
public async Task<HttpResponseMessage> CallHttpClientPostAsync(string requestUri, HttpContent requestBody)
{
AddHttpRequestHeader(httpClient);
var response = await httpClient.PostAsync(requestUri, requestBody); //Potential thread synchronization issue???
return response;
}
public HttpResponseMessage CallHttpClientGet(string requestUri)
{
AddHttpRequestHeader(httpClient);
var response = httpClient.GetAsync(requestUri).Result; //Potential thread synchronization issue???
return response;
}
private void AddHttpRequestHeader(HttpClient client)
{
string HeaderName = "CorrelationId";
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(Properties.Settings.Default.HttpClientAuthHeaderScheme, GetTokenFromClaims()); //Race condition???
if (client.DefaultRequestHeaders.Contains(HeaderName))
client.DefaultRequestHeaders.Remove(HeaderName);
client.DefaultRequestHeaders.Add(HeaderName, Trace.CorrelationManager.ActivityId.ToString());
}
}
【问题讨论】:
-
CallHttpClientGet不是异步的任何原因?通过调用.Result,您正在阻塞线程并引发潜在的死锁。
标签: asp.net thread-safety httprequest static-libraries dotnet-httpclient