有时我们的网站速度变慢并且 RAM 使用率大幅上升。然后应用程序池停止,我必须重新启动它。然后在 RAM 突然再次飙升并且应用程序池很快停止之前几天没问题。 CPU 不高。
在应用程序池停止之前,我注意到我们的一个页面总是挂起。它挂起的行是 ResourceSet 上的 foreach :
var englishLocations = Lang.Countries.ResourceManager.GetResourceSet(new CultureInfo("en-GB"),true,true);
foreach(DictionaryEntry entry2 in englishLocations) // THIS LINE HANGS
我们在不同的盒子上部署了相同的代码,但并没有发生这种情况。两个盒子之间的主要区别是:
坏箱子
- Window Server 2008 R2 标准 SP 1
- IIS 7.5.7600.16385
- .NET 4.5
- 24GB 内存
好盒子
- Windows Server 2008 服务器 SP 2
- IIS 7.0.6000.16386 SP 2
- .NET 4.0
- 24GB 内存
我已尝试按照此处所述将 uploadReadAheadSize="0"添加到 web.config 中:
哪个没用。
为什么 foreach 会挂起?它卡在第一个项目上,实际上是卡在 foreach 上。
谢谢。
最佳答案
我知道这是一篇旧文章,但无论如何......在遍历 ResourceSet 并同时从相同的资源中检索其他对象时,可能会出现死锁。
问题在于,当使用 ResourceSet 时,迭代器会锁定 ResourceReader 的内部资源缓存 http://referencesource.microsoft.com/#mscorlib/system/resources/resourcereader.cs,1389然后在 AllocateStringNameForIndex 方法中锁定读取器本身:http://referencesource.microsoft.com/#mscorlib/system/resources/resourcereader.cs,447
lock (_reader._resCache) {
key = _reader.AllocateStringForNameIndex(_currentName, out _dataPosition); // locks the reader
获取一个对象以相反的顺序取出相同的锁:
http://referencesource.microsoft.com/#mscorlib/system/resources/runtimeresourceset.cs,300 和 http://referencesource.microsoft.com/#mscorlib/system/resources/runtimeresourceset.cs,335
lock(Reader) {
....
lock(_resCache) {
_resCache[key] = resLocation;
}
}
这可能会导致死锁。我们最近遇到了这个确切的问题..
关于c# - foreach 神秘地卡在 ResourceSet 的第一项上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17965347/