foreach神秘地挂在ResourceSet的第一项上

Typ*_*son 15 c# asp.net-mvc performance

偶尔我们的网站会慢下来,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
Run Code Online (Sandbox Code Playgroud)

我们在不同的盒子上部署了相同的代码,但这不会发生.两个方框之间的主要区别是:

坏盒子

  • Window Server 2008 R2标准SP 1
  • IIS 7.5.7600.16385
  • .NET 4.5
  • 24GB内存

好盒子

  • Window Server 2008 Server SP 2
  • IIS 7.0.6000.16386 SP 2
  • .NET 4.0
  • 24GB内存

我已经尝试将uploadReadAheadSize ="0"添加到web.config中,如下所述:

http://rionscode.wordpress.com/2013/03/11/resolving-controller-blocking-within-net-4-5-and-asp-net-mvc/

哪个没用.

为什么foreach会挂起来?它挂在第一个项目上,实际上是在foreach上.

谢谢.

Joh*_*per 9

我知道这是一个旧帖子,但是......当迭代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
Run Code Online (Sandbox Code Playgroud)

获取对象以相反的顺序取出相同的锁:

http://referencesource.microsoft.com/#mscorlib/system/resources/runtimeresourceset.cs,300http://referencesource.microsoft.com/#mscorlib/system/resources/runtimeresourceset.cs,335

lock(Reader) {
    ....
    lock(_resCache) {
       _resCache[key] = resLocation;
    }
}
Run Code Online (Sandbox Code Playgroud)

这可能导致僵局.我们最近有这个问题..

  • 几年前在完全相同的方法中陷入僵局.MS打开了coreclr源代码,所以我做了一个修复 - https://github.com/dotnet/coreclr/pull/75.它已经被淹没了.我希望它将包含在下一个桌面CLR版本中. (3认同)

use*_*326 1

根据另一个答案,让您了解如何使用 try catch 模型?也许它挂起是因为该资源不可用/锁定/..权限等。

var englishLocations = Lang.Countries.ResourceManager.GetResourceSet(new CultureInfo("en-GB"),true,true); 
foreach(DictionaryEntry entry2 in englishLocations) // THIS LINE HANGS



ResourceManager CultureResourceManager = new ResourceManager("My.Language.Assembly", System.Reflection.Assembly.GetExecutingAssembly());
ResourceSet resourceSet = CultureResourceManager.GetResourceSet("sv-SE", true, true);
try { resourceSet.GetString("my_language_resource");}
catch (exception ex) {  // from here log your error ex to wherever you like with some code }
Run Code Online (Sandbox Code Playgroud)