asp.net - ASP.net HttpRequest 上的静态 HttpClient 线程安全

标签 asp.net thread-safety httprequest static-libraries dotnet-httpclient

我们正在为 HttpClient 创建一个包装器。因为我们将遵循 https://github.com/mspnp/performance-optimization 中的性能优化指导.我们希望避免反模式 - 该文档中提到的不正确实例化。我将此指南推荐给我的团队以使用静态 HttpClient。我得到的反馈是关于线程安全的。每个请求都有一个包含用户声明的 header 。由于我有一个静态 HttpClient,它会是线程安全的吗?如果我们有多个请求同时访问代码(例如 GET),设置 header 会是竞争条件吗?我们有如下实现。

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());
}

}

最佳答案

您的团队是正确的,这远非线程安全。考虑这种情况:

  • 线程 A 将 CorrelationId header 设置为“foo”。
  • 线程 B 将 CorrelationId header 设置为“bar”。
  • 线程 A 发送请求,请求中包含线程 B 的 CorrelationId。

  • 更好的方法是让您的 CallXXX 方法创建新的 HttpRequestMessage对象,并在这些对象上设置标题,然后使用 HttpClient.SendAsync调用电话。

    还要记住,重复使用 HttpClient实例仅在您对同一主机进行多次调用时才有用。

    关于asp.net - ASP.net HttpRequest 上的静态 HttpClient 线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29762390/

    相关文章:

    c# - 在 GridView C# 中更新列行

    multithreading - 使用内存sqlite数据库时,QSqlQuery是否有线程锁

    sockets - libc套接字线程安全吗?

    asp-classic - 经典 ASP : run some code at the start of every request before processing actual . asp 文件

    json - 从网络服务中获取 json 数组

    Java servlet 处理应用程序/八位字节流用于图像上传

    c# - When a certain item on dropdownlist1 is selected, select automatically a certain item on dropdownlist2

    javascript - 返回操作的语法不正确

    c# - 从列表中删除多个值

    java - 代号一container.revalidate()有时会抛出IndexOutOfBoundsException