【问题标题】:HttpContent: An item with the same key has already been addedHttpContent:已添加具有相同键的项
【发布时间】:2017-08-20 20:01:25
【问题描述】:

我们在代码库中看到了以下堆栈跟踪:

System.ArgumentException: An item with the same key has already been added. 
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add) 
   at System.Net.Http.Headers.HttpHeaders.AddHeaderToStore(String name, HeaderStoreItemInfo info) 
   at System.Net.Http.Headers.HttpHeaders.SetParsedValue(String name, Object value) 
   at System.Net.Http.Headers.HttpContentHeaders.get_ContentLength() 
   at System.Net.Http.HttpClientHandler.PrepareAndStartContentUpload(RequestState state) 

并将其缩小到我们调用的代码中的某个地方

HttpContent.ReadAsStringAsync()

当这种情况发生时,我们确定 HttpContent 的实例正被多个线程使用,所有这些线程都以某种方式试图读取实际内容。尚未弄清楚内容的阅读如何影响标题。

如果可以执行 HttpContent 的深度克隆,假设所有内容负载已下载,我们会研究此选项。

有人遇到过这个问题,如果是,你是怎么解决的?

提前致谢。

【问题讨论】:

  • 请提供一些复制代码。看起来您正在尝试上传内容,但由于某种原因它无法添加 Content-Length 标头,但如果没有更多代码就很难判断。

标签: c# race-condition httpcontent


【解决方案1】:

您的堆栈跟踪与读取响应相关联对我来说毫无意义。似乎更有可能的是,在您发出请求之前,您的线程正在努力添加标头。也许与异步调试有些混淆? 当我有这样的一行时,我已经看到了这一点(客户端是 HttpClient)

client.DefaultRequestHeaders.AcceptEncoding.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("gzip"));

在每个线程可以执行的代码上,它变成了一个竞争条件,因为我相信 httpclient 在添加它之前会检查是否存在,然后如果在这段时间之间有两个线程尝试添加它,它会像这样崩溃。根据您的设置,您可能需要将类似这样的内容移入初始化或对其进行锁定。

【讨论】:

    猜你喜欢
    • 2021-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-15
    相关资源
    最近更新 更多