2012-06-05 10 views
11

langsam bin ich überlastet ...Anwendung friert außerhalb von Visual Studio ein. Beim Starten von Visual Studio funktioniert es

Ich habe eine große Anwendung mit Threading, Timer, aufrufen (nicht BeginInvoke, so ist es synchron) und Application.DoEvents.

Es ist zu viel hier zu posten und ich weiß nicht, wo das Problem wirklich ist.

Jede Methode von mir ist in einem Versuch zu fangen. Jeder Fang wird protokolliert.

Wenn ich meine Anwendung von Visual Studio (F5) oder während der Profilerstellung über Ants starte, gibt es kein Problem. Die Anwendung läuft seit einigen Tagen. Aber sobald ich die gleiche Debug-Version über Windows Explorer starte, friert es alle paar Stunden ein. Es friert ohne Ausnahme oder so. Wenn ich Visual Studio an diese Anwendung anschließe und sie aufbringe, stoppt sie bei Application.Run (new Form1());

Ich bin wirklich verwirrt und habe keine Idee, es zu reparieren.

Es ist eine .net 3.5 WinForms-Anwendung

Es sieht aus wie ein Thread hier hängt:

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

dieser Ausschnitt ist Teil eines Timer-Ereignis

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

bearbeiten

Ein Beispiel für DoEvents(). Dies ist in einem Schloss() und in einem invoke

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"); 
    } 
} 

Derzeit ich die System.Windows.Forms.Timer und einige Schlösser verwenden, aber es ist keine Besserung.

Okay, habe ich WinDbg einige Informationen

bearbeiten zu erhalten:! 14.06.2012

Themen

         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

Sie haben eine Sackgasse an Ihren Händen. Diese sind jedoch schwer zu diagnostizieren. – zmbq

+0

kann Speicherlecks sein, so dass es nicht genügend Speicher hat [Speicherleck in cis] (http://stackoverflow.com/questions/620733/memory-leak-in-c-sharp), [how-to-detect-memory -leaks in-c-sharp-Anwendung] (http://stackoverflow.com/questions/2259433/how-to-detect-memory-leaks-in-c-sharp-application)? – PresleyDias

+0

Yup, würde dasselbe wie zmbq sagen. Wird es von der IDE aus ausgeführt, verlangsamt es sich enorm, so dass Sperren aus Nebenläufigkeit mit geringerer Wahrscheinlichkeit auftreten. –

Antwort

8

a Könnte möglich e Deadlock in einem Hintergrundfaden. Versuchen Sie, andere Threads zu sehen, die Ihre App blockieren könnten.

Toolbar -> Debug -> Windows -> Threads 

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

sollte es mehrere Threads sein, und wenn Sie ein Sie die Zeile sehen einen Doppelklick auf, wo sie Ihre App zu stoppen.

Und wenn Sie diese Zeile im Code:

Control.CheckForIllegalCrossThreadCalls = false; 

Set es wieder wahr.Eine mögliche Ursache für tote Sperren sind Hintergrund-Thread-Zugriffssteuerungen.

Anstatt dies von einem Backgroud Threads zu schreiben.

button1.Text = "hello" 

dies schreiben.

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

danke. Mit den Threads habe ich den bearbeiteten Teil meines Main gefunden Frage –

+0

Sie könnten versuchen, 'BeginInvoke' anstelle von' Invoke' zu ​​verwenden, die nicht auf den Aufruf warten, aber ich würde einen 'System.Windows.Forms.Timer' verwenden, verwenden Sie diesen Code in einem Windows Forms-Kontext Das Windows Forms Timer Tick-Ereignis wird im GUI-Thread ausgelöst, sodass Sie sich keine Gedanken über die Synchronisation machen müssen. " –

+0

Momentan verwende ich den System.Windows.Forms.Timer und einige Sperren, aber es gibt keine Verbesserung. –

3

Wenn es friert, werden Sie wahrscheinlich einen Stillstand sehen. Eine der besten Möglichkeiten, die ich gefunden habe, um einen Deadlock zu finden, ist die Verwendung eines Crash-Dump und Sosex.

Hier ist ein guter Artikel über die Verwendung dieser Technik (es ist asp.net, aber die gleichen Prinzipien gelten): http://blogs.msdn.com/b/tess/archive/2010/04/27/debugging-a-classic-readerwriterlock-deadlock-with-sosex-dll.aspx

die App laufen lassen, bis es gefriert, und nehmen Sie eine hängen dump: http://blogs.msdn.com/b/tess/archive/2006/10/16/net-hang-debugging-walkthrough.aspx

0

Invoke ist gefährlich und ich

this.Invoke((MethodInvoker)...

mit

ersetzen würde empfehlen, leicht dazu führen, Deadlocks auf unerwartete Weise können

this.BeginInvoke((MethodInvoker)...

die den Anrufer nicht blockieren und das Problem wahrscheinlich beheben wird.

bearbeiten, wenn es nicht ist, müssen Sie warten, bis es Deadlocks und dann windbg verwenden, um zu sehen, warum Sie festgefahren sind.

0

Bei der Ausführung von VS wird es einen Debugger-Thread injizieren, der einige Nachrichtenrouting ändert. Sie haben möglicherweise ein Problem mit Ihrer Invoke(...) Blockierung auf etwas, das auf eine Nachricht in der Warteschlange wartet, aber unter dem Debugger werden die Gewinnnachrichten in einer anderen Reihenfolge verarbeitet.

IIUC Sie benötigen keine Sperren mit System.Windows.Forms.Timer, da es win message pump verwendet, so dass Timer-Ereignisse immer im GUI-Thread verarbeitet werden (es sei denn, etwas anderes in Ihrer App führt Code auf TheAdPool oder in dedizierten Hintergrundthreads).

Also, nichts in Ihrem Beispielcode beinhaltet Threading, es sei denn, das Webbrowser-Steuerelement löst seine Ereignisse auf einem Hintergrund-Thread (in diesem Fall POST zurück zum UI-Thread mit BeginInvoke()). Sobald alle Anwendungssteuerelemente im Hauptthread der Benutzeroberfläche ausgeführt wurden, entfernen Sie die Sperren (als Debughilfe). Bitte posten Sie weitere Informationen zur Hintergrundverarbeitung und den bisherigen Ergebnissen.

Verwandte Themen