我们的系统并行处理多个实时计算流 - 每秒大约300-500次计算。我们在生产中偶尔会看到ThreadPool扩展到400-500个线程的问题,并且性能下降到爬行状态。计算仍在继续,但速度要慢得多。
VS中的进程转储+并行堆栈窗口显示数百个带有调用堆栈的线程池线程,这些线程都以TimeZoneInfo中的Monitor.Enter
结尾。我们的计算涉及时区转换。
我原本以为我们应该能够每秒获得数千次或数百万次锁定而没有问题。这个锁支持几百个线程的事实令人惊讶。应用程序继续处理工作的事实意味着这不是僵局,只是非常昂贵的争用。
这里是一个示例callstack - 所有线程都是变体:
[Managed to Native Transition]
mscorlib.dll!System.Threading.Monitor.Enter(object obj, ref bool lockTaken) Unknown
mscorlib.dll!System.TimeZoneInfo.ConvertTimeToUtc(System.DateTime dateTime, System.TimeZoneInfoOptions flags) Unknown
mscorlib.dll!System.DateTime.ToUniversalTime() Unknown
<our code>
mscorlib.dll!System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(object state) Unknown
...
我们正在运行.Net 4.0。看起来TimeZoneInfo中的锁定实现在.Net 4.5中已经改变 - 4.5中的锁定要少得多。
搜索这个问题并没有产生太多影响。看起来在.Net 4.5中可能已经解决了这个问题。有没有人知道可能与此相关的知识?