2010-11-17 7 views
34

Ho un'applicazione che utilizza contatori delle prestazioni, che ha funzionato per mesi. Ora, sulla mia macchina di sviluppo e su un'altra macchina per sviluppatori, ha iniziato a bloccarsi quando chiamo PerformanceCounterCategory.Exists. Per quanto posso dire, si blocca indefinitamente. Non importa quale categoria utilizzo come input e le altre applicazioni che utilizzano l'API mostrano lo stesso comportamento.Cosa rendere PerformanceCounterCategory.Exists si blocca indefinitamente?

Il debug (tramite MS Symbol Server) ha indicato che è una chiamata a Microsoft.Win32.RegistryKey che si blocca. Ulteriori indagini dimostra che è questa linea che pende:

while (Win32Native.ERROR_MORE_DATA == (r = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref sizeInput))) { 

Questo è fondamentalmente un ciclo che tenta di allocare memoria sufficiente per i dati dei contatori delle prestazioni. Inizia da size = 65000 e fa alcune iterazioni. Nella quarta chiamata, quando si blocca size = 520000, Win32Native.RegQueryValueEx.

Inoltre, piuttosto worringly, ho trovato questo commento nella fonte di riferimento per PerformanceCounterLib.GetData:

// Win32 RegQueryValueEx for perf data could deadlock (for a Mutex) up to 2mins in some 
    // scenarios before they detect it and exit gracefully. In the mean time, ERROR_BUSY, 
    // ERROR_NOT_READY etc can be seen by other concurrent calls (which is the reason for the 
    // wait loop and switch case below). We want to wait most certainly more than a 2min window. 
    // The curent wait time of up to 10mins takes care of the known stress deadlock issues. In most 
    // cases we wouldn't wait for more than 2mins anyways but in worst cases how much ever time 
    // we wait may not be sufficient if the Win32 code keeps running into this deadlock again 
    // and again. A condition very rare but possible in theory. We would get back to the user 
    // in this case with InvalidOperationException after the wait time expires. 

qualcuno ha visto questo comportamento prima? Cosa posso fare per risolvere questo?

+2

Ricerca molto bella, +1. Sì, vai avanti e preoccupati, l'intera API del perf-counter ha avuto un afaict irraggiungibile. Un modello troppo semplice che non può più essere aggiunto alla prossima versione di Windows. Vista ha fatto una grande pausa da questo. Buona fortuna! –

risposta

24

Questo problema è stato risolto e, poiché non sono state fornite risposte, aggiungerò una risposta qui nel caso in cui la domanda venga trovata nelle ricerche future.

Alla fine ho risolto questo errore interrompendo il servizio di spooler di stampa (come misura temporanea).

Sembra che la lettura dei contatori delle prestazioni abbia effettivamente bisogno di enumerare le stampanti sul sistema (confermato da un dump WinDbg di un processo di sospensione, in cui posso vedere nella traccia dello stack che winspool sta enumerando le stampanti, ed è bloccato una chiamata di rete). Questo era ciò che in realtà non funzionava sul sistema (e abbastanza sicuro, aprendo anche la finestra "Dispositivi e stampanti"). Mi sconcerta che un problema di stampante/rete possa effettivamente far scendere i contatori delle prestazioni. Si potrebbe pensare che ci fosse una sorta di fail-safe integrato per un caso del genere.

Quello che sto indovinando, è che questo è causato da un cattivo stampante/driver sulla rete. Non ho ancora riattivato la stampa sui sistemi interessati, dato che stiamo cercando la cattiva stampante.

+1

È possibile che la lettura dei contatori delle prestazioni * causi l'arresto dello spooler di stampa? Sparare una seconda richiesta per alcune risorse che blocca qualcosa che la prima richiesta deve terminare o somesuch? Suppongo che questo non cambi la causa reale - un cattivo driver - ma mi chiedo se il problema non verrà visualizzato a meno che non lo si provochi nel modo che hai precedentemente descritto. –

+1

Questa risposta ci ha aiutato a risolvere un problema correlato [nuovo PerformanceCounter()] (http://stackoverflow.com/questions/2868068). Rimozione di una vecchia stampante ha impedito il blocco e almeno ha mostrato un messaggio di errore che stiamo perseguendo. – crokusek

+0

Sto riscontrando un problema simile da un componente aggiuntivo di Outlook. Quale strumento hai usato per eseguire il debug? Attualmente ho Process Monitor, ma sto avendo problemi a trovare il deadlock –