2013-07-31 11 views
15

Occasionalmente il nostro sito rallenta e l'utilizzo della RAM aumenta in modo massiccio. Quindi il pool di app si arresta e devo riavviarlo. Poi va bene per alcuni giorni prima che la RAM improvvisamente picchi di nuovo e il pool di app si fermi presto. La CPU non è alta.foreach si blocca misteriosamente sul primo elemento di un ResourceSet

Prima che il pool di app si arresti, ho notato che una delle nostre pagine si blocca sempre. La linea si blocca su un foreach su un ResourceSet:

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

Abbiamo lo stesso codice distribuito su una scatola di diverso e questo non accade. Le principali differenze tra le due caselle sono:

Bad scatola

  • Window Server 2008 R2 Standard SP 1
  • IIS 7.5.7600.16385
  • .NET 4.5
  • 24GB RAM

Buona scatola

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

Ho provato ad aggiungere uploadReadAheadSize = "0" al web.config come descritto qui:

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

Quale non ha funzionato.

Perché dovrei aspettare? È sospeso sul primo oggetto, in realtà sul foreach.

Grazie.

+0

Sei sicuro? Perché le dimensioni del file delle risorse saranno molto importanti. Se la dimensione del file di risorse è grande, esiste la possibilità che il riempimento della var con i valori del file di risorse possa essere un problema reale. Prova a dare alla variabile un tipo di dati –

+0

, ne sono sicuro, da debugging per settimane. Il file di risorse contiene 250 voci. Ho molti più file di risorse per coprire diversi elementi del sito. –

+0

Forse c'è un problema con le risorse di fallback. Hai provato a chiamarlo senza caricare fallback, come'GetResourceSet (new CultureInfo ("en-GB"), true, FALSE); '? – developer10214

risposta

1

Sulla base di un'altra risposta per darti un'idea di come utilizzare un modello try catch? Forse si blocca perché quella risorsa è neanche disponibile /..permissions/bloccati ecc

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 } 
2

ho vissuto problema molto simile.

Ogni tanto IIS si blocca, e vedrei il numero di richieste appena seduto lì. Erano tutti nello stato ExecuteRequestHandler e con il nome del modulo ManagedPipelineHandler.

Dopo aver esaminato con Process Explorer, ho potuto vedere che tutti erano seduti a mscorlib.dll!ResourceEnumerator.get_Entry, la traccia di stack aggiuntiva suggeriva un'azione NGen e quindi ntdll.dll!WaitForMultipleObjects.

La mia ipotesi di lavoro è che quando più thread iniziano a enumerare quelle risorse, possiamo imbattersi in un deadlock (possibilmente su qualche generazione di file di codice nativo), e tutti i thread successivi continuano ad accumularsi.

Per risolvere il problema, ho appena creato una sezione critica attorno a questo blocco di codice, per garantire che venga eseguita in sequenza - Non ho riscontrato il problema da allora.

private static readonly object ResourceLock = new object(); 

public static MvcHtmlString SerializeGlobalResources(this HtmlHelper helper) 
{ 
    lock (ResourceLock) 
    { 
     // Existing code goes here .... 
    } 
} 
8

So che è un vecchio post, ma comunque ... c'è il potenziale di una situazione di stallo in cui l'iterazione di un ResourceSet e allo stesso tempo il recupero di qualche altro oggetto tramite delle stesse risorse.

Il problema è che quando si utilizza un ResourceSet all'iteratore estrae serrature cache risorsa interna della ResourceReader http://referencesource.microsoft.com/#mscorlib/system/resources/resourcereader.cs,1389 e poi nel metodo AllocateStringNameForIndex prende un blocco sul lettore stesso: http://referencesource.microsoft.com/#mscorlib/system/resources/resourcereader.cs,447

lock (_reader._resCache) { 
    key = _reader.AllocateStringForNameIndex(_currentName, out _dataPosition); // locks the reader 

Come un oggetto tira fuori gli stessi blocchi int ordine inverso:

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

lock(Reader) { 
    .... 
    lock(_resCache) { 
     _resCache[key] = resLocation; 
    } 
} 

Ciò può portare a un deadlock. Abbiamo avuto questo problema esattamente di recente ..

+3

Trovato un deadlock esattamente nello stesso paio di metodi alcuni anni fa. MS ha aperto il codice sorgente di coreclr, quindi ho apportato una correzione: https://github.com/dotnet/coreclr/pull/75. È già mere. Spero che sarà incluso nella prossima versione CLR desktop. – PashaPash

+1

Qualcuno capisce se la correzione è già inclusa in una versione? Le versioni di rilascio non sembrano essere gestite sul repository GitHub. –

+0

Cercate le fonti su http://referencesource.microsoft.com/download.html. Il problema è stato risolto in 4.6, qualsiasi cosa più vecchia ti porterà al punto morto. – plmaheu

Problemi correlati