2012-06-05 14 views
11

piano piano sto oberati di lavoro ...L'applicazione si blocca all'esterno di Visual Studio. Mentre a partire da Visual Studio funziona

Ho un enorme applicazione con filettatura, timer, richiamare (non BeginInvoke, quindi è sincrono) e Application.DoEvents.

È troppo per postare qui e non so dove sia realmente il problema.

Ogni mio metodo è all'interno di un tentativo di cattura. Ogni presa è registrata.

Se avvio la mia applicazione da Visual Studio (F5) o mentre la sto profilando tramite le formiche non ci sono problemi. L'applicazione funziona da alcuni giorni. Ma non appena avvio la stessa versione di debug tramite Windows Explorer, si blocca ogni poche ore. Si blocca senza alcuna eccezione o così. Se collego Visual Studio a questa applicazione e la interrompo, si ferma su Application.Run (new Form1());

Sono davvero confuso e non ho idea di ripararlo.

Si tratta di un'applicazione .NET 3.5 WinForms

Sembra che un thread si blocca qui:

if (grabber.InvokeRequired) 
{ 
    Console.WriteLine("grabber.InvokeRequired"); 
    this.Invoke((MethodInvoker) delegate { grabber.Navigate("http://www.google.de"); }); // <-- hang 
} 
else 
{ 
    grabber.Navigate(ig.StartUrl); 
} 

questo frammento è parte di un evento timer

_timeout = new System.Timers.Timer(10000); 
_timeout.Elapsed += new ElapsedEventHandler(OnWatchDogBark); 

Modifica

Un esempio per DoEvents(). Questo è in un blocco() e in un invocare

grabber.DocumentCompleted -= grabber_DocumentCompleted; 
grabber.Navigate("http://www.google.de"); 

while (grabber.ReadyState != WebBrowserReadyState.Complete) 
{ 
    timeout--; 
    Application.DoEvents(); 
    Thread.Sleep(200); 

    if (timeout < 0) 
    { 
     timeout = 50; 
     grabber.Navigate("http://www.google.de"); 
    } 
} 

Attualmente io uso lo System.Windows.Forms.Timer e alcune ciocche, ma non v'è alcun miglioramento.

Va bene ho usato WinDbg per ottenere alcune informazioni

Edit:!! 14.06.2012

discussioni

         PreEmptive GC Alloc   Lock 
     ID OSID ThreadOBJ State  GC  Context  Domain Count APT Exception 
    0 1 37ec 007cab18  6020 Enabled 00000000:00000000 007c8510  0 STA System.ArgumentException (02762ba8) 
    2 2 85b8 007d7c38  b220 Enabled 00000000:00000000 007c8510  0 MTA (Finalizer) 
XXXX 3 0 06e9f548  9820 Enabled 00000000:00000000 007c8510  0 Ukn 
    21 5 3464 0d6dc598 200b020 Enabled 28cb5820:28cb5fe8 007c8510  0 MTA 
    22 6 62b0 0d6db9e0 200b220 Enabled 00000000:00000000 007c8510  0 MTA 
    23 7 8e58 0d6db5f8 80a220 Enabled 00000000:00000000 007c8510  0 MTA (Threadpool Completion Port) 
XXXX 4 0 06f62d40 1801820 Enabled 00000000:00000000 007c8510  0 Ukn (Threadpool Worker) 
XXXX f 0 132a3290 1801820 Enabled 00000000:00000000 007c8510  0 Ukn (Threadpool Worker) 
XXXX 10 0 132a3678 1801820 Enabled 00000000:00000000 007c8510  0 Ukn (Threadpool Worker) 
XXXX e 0 132a26d8 1801820 Enabled 00000000:00000000 007c8510  0 Ukn (Threadpool Worker) 
XXXX 9 0 0d6db210 1801820 Enabled 00000000:00000000 007c8510  0 Ukn (Threadpool Worker) 

dlk

Examining SyncBlocks... 
Scanning for ReaderWriterLock instances... 
Scanning for holders of ReaderWriterLock locks... 
Scanning for ReaderWriterLockSlim instances... 
Scanning for holders of ReaderWriterLockSlim locks... 
Examining CriticalSections... 
Could not find symbol ntdll!RtlCriticalSectionList. 
No deadlocks detected. 
+1

Hai una situazione di stallo nelle tue mani. Questi sono difficili da diagnosticare, però. – zmbq

+0

potrebbe essere una perdita di memoria che fa esaurire la memoria [perdita di memoria in c sharp] (http://stackoverflow.com/questions/620733/memory-leak-in-c-sharp), [how-to-detect-memory -leaks in-c-sharp-application] (http://stackoverflow.com/questions/2259433/how-to-detect-memory-leaks-in-c-sharp-application)? – PresleyDias

+0

Sì, direi lo stesso di zmbq. Eseguirlo dall'IDE rallenta enormemente, quindi è meno probabile che si verifichino blocchi dalla concorrenza. –

risposta

8

potrebbe essere un possibl e Deadlock in una discussione in background. Prova a guardare altri thread che potrebbero bloccare la tua app.

Toolbar -> Debug -> Windows -> Threads 

http://msdn.microsoft.com/en-us/library/w15yf86f.aspx

Ci dovrebbe essere più thread e se si fa doppio clic su uno che si vede la linea in cui si ferma la vostra applicazione.

E se questa riga nel codice:

Control.CheckForIllegalCrossThreadCalls = false; 

Impostare a true nuovo.Una possibile causa per i dead lock è il thread in background che accede ai controlli.

Invece di scrivere questo da un thread backgroud.

button1.Text = "hello" 

scrivere questo.

this.Invoke(() => button1.Text = "hello"); 
+0

grazie. Con i thread ho trovato la parte modificata del mio main domanda –

+0

Si potrebbe provare a utilizzare 'BeginInvoke' piuttosto che' Invoke' che non attenderà il ritorno della chiamata, ma userei un 'System.Windows.Forms.Timer', si sta utilizzando questo codice in un contesto Windows Form , giusto? L'evento Ticker Timer di Windows Form si attiva nel thread della GUI, quindi non devi preoccuparti della sincronizzazione –

+0

Attualmente utilizzo System.Windows.Forms.Timer e alcuni blocchi, ma non ci sono miglioramenti. –

3

Se si blocca, è probabile che si stia guardando un punto morto. Uno dei modi migliori che ho trovato per trovare un deadlock è usare un crash dump e sosex.

Ecco un buon articolo sull'utilizzo di questa tecnica (è asp.net, ma si applicano gli stessi principi): http://blogs.msdn.com/b/tess/archive/2010/04/27/debugging-a-classic-readerwriterlock-deadlock-with-sosex-dll.aspx

lascia passare l'applicazione fino a quando non si blocca, e prendere una discarica appendere: http://blogs.msdn.com/b/tess/archive/2006/10/16/net-hang-debugging-walkthrough.aspx

0

Invoke è pericoloso e può facilmente causare situazioni di stallo in modi inaspettati vi consiglio di sostituire

this.Invoke((MethodInvoker)...

con

this.BeginInvoke((MethodInvoker)...

che non bloccherà il chiamante e probabilmente risolverà il problema.

modifica se non è necessario attendere fino a quando non si blocca e quindi utilizzare windbg per verificare il motivo per cui si è bloccati.

0

Durante l'esecuzione da VS, viene iniettato un thread di debugger, che modifica l'instradamento dei messaggi. Potresti avere un problema con il tuo blocco Invoke(...) su qualcosa che è in attesa su un messaggio in coda, ma sotto il debugger i messaggi di vincita vengono elaborati in un ordine diverso.

IIUC non necessita di blocchi con System.Windows.Forms.Timer perché utilizza pump dei messaggi di vincita, quindi gli eventi del timer vengono sempre elaborati sul thread GUI (a meno che qualcos'altro nella tua app stia eseguendo il codice sul TheadPool o in thread di background dedicati).

Quindi, nel codice di esempio non è coinvolto il threading, a meno che il controllo del browser Web non attivi i suoi eventi su un thread in background (in tal caso POST quelli indietro nel thread dell'interfaccia utente, con BeginInvoke()). Una volta che tutto il controllo dell'applicazione in esecuzione sul thread principale dell'interfaccia utente rimuove i blocchi (come aiuto di debug). Per favore pubblica più informazioni sull'elaborazione in background e sui risultati fino ad oggi.