小编Gre*_*ght的帖子

.NET:由于Dictionary,HttpClient中的CPU使用率是100%?

简短问题:
是否有其他人在使用单例.NET HttpClient时遇到问题,其中应用程序将处理器固定为100%直到重新启动?

详细信息:
我正在运行一个Windows服务,它可以执行基于计划的连续ETL.其中一个数据同步线程偶尔会死掉,或者开始失控,并将处理器固定在100%.

我很幸运能够在有人重新启动服务(标准修复程序)之前看到这种情况发生,并且能够获取转储文件.

在WinDbg(带有SOS和SOSEX)中加载它,我发现我有大约15个线程(主处理线程的子任务)都运行相同的堆栈跟踪.但是,似乎没有任何死锁.IE高利用率线程正在运行,但从未完成.

相关的堆栈跟踪段如下(地址省略):

System.Collections.Generic.Dictionary`2[[System.__Canon, mscorlib],[System.__Canon, mscorlib]].FindEntry(System.__Canon)
System.Collections.Generic.Dictionary`2[[System.__Canon, mscorlib],[System.__Canon, mscorlib]].TryGetValue(System.__Canon, System.__Canon ByRef)
System.Net.Http.Headers.HttpHeaders.ContainsParsedValue(System.String, System.Object)
System.Net.Http.Headers.HttpGeneralHeaders.get_TransferEncodingChunked()
System.Net.Http.Headers.HttpGeneralHeaders.AddSpecialsFrom(System.Net.Http.Headers.HttpGeneralHeaders)
System.Net.Http.Headers.HttpRequestHeaders.AddHeaders(System.Net.Http.Headers.HttpHeaders)
System.Net.Http.HttpClient.SendAsync(System.Net.Http.HttpRequestMessage, System.Net.Http.HttpCompletionOption, System.Threading.CancellationToken)
...
[Our Application Code]
Run Code Online (Sandbox Code Playgroud)

根据这篇文章(以及我发现的其他文章),字典的使用不是线程安全的,如果以多线程方式访问字典,则无限循环是可能的(如直接崩溃).

我们的应用程序代码没有明确使用字典.那么堆栈跟踪中提到的字典在哪里?

通过.NET Reflector,看起来 HttpClient使用字典来存储已在"DefaultRequestHeaders"属性中配置的任何值.因此,通过HttpClient发送的任何请求都会触发单个非线程安全字典的枚举(为了将默认标头添加到请求中),这可能会无限地旋转(或终止)所涉及的线程.发生腐败.

微软直言不讳地说HttpClient类是线程安全的.但在我看来,如果已将任何标头添加到HttpClient的DefaultRequestHeaders中,则不再适用.

我的分析似乎表明这是真正的根本问题,一个简单的解决方法是简单地从不使用可以以多线程方式使用HttpClient的DefaultRequestHeaders.

但是,我正在寻找一些确认,我没有咆哮错误的树.如果这是正确的,它似乎是.NET框架中的一个错误,我自然会怀疑.

对于罗嗦的问题感到抱歉,但感谢你提出的任何意见.

.net c# multithreading dictionary dotnet-httpclient

8
推荐指数
1
解决办法
1852
查看次数

标签 统计

.net ×1

c# ×1

dictionary ×1

dotnet-httpclient ×1

multithreading ×1