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

本文关键字:一项 ResourceSet foreach | 更新日期: 2023-09-27 18:25:33

偶尔我们的网站会变慢,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内存

好盒子

  • Window Server 2008服务器SP 2
  • IIS 7.0.6000.16386第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神秘地挂在ResourceSet的第一项上

我知道这是一篇旧帖子,但尽管如此。。。当在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;
    }
}

这可能会导致僵局。我们最近遇到了这个问题。。

我遇到了非常类似的问题。

每隔一段时间,IIS就会挂起,我就会看到很多请求就在那里。它们都处于状态ExecuteRequestHandler,并且具有ManagedPipelineHandler模块名称。

在使用process explorer进行调查后,我可以看到它们都位于mscorlib.dll!ResourceEnumerator.get_Entry,额外的堆栈跟踪建议一些NGen操作,然后是ntdll.dll!WaitForMultipleObjects

我的工作假设是,当多个线程开始枚举这些资源时,我们可能会遇到死锁(可能是在生成一些本机代码文件时),然后所有后续线程都会继续堆积。

为了解决这个问题,我只是围绕这个代码块创建了一个关键部分,以确保它按顺序执行——从那以后我就没有遇到过这个问题。

private static readonly object ResourceLock = new object();
public static MvcHtmlString SerializeGlobalResources(this HtmlHelper helper)
{
    lock (ResourceLock)
    {
        // Existing code goes here ....
    }
}

基于另一个答案,让您了解使用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 }