Control.Invoke () hängt die Anwendung

7

Ich zeige eine Animation, während mein Steuerelement die Daten lädt. Wenn der Thread fertig ist, verstecke ich die Animation und zeige das Steuerelement an. Also führe ich diesen Code aus einem Thread aus:

%Vor%

Manchmal, wenn ich diesen Code ausführe, wird der Haupt-Thread im folgenden Code gehängt:

%Vor%

}

Ich bin mir nicht sicher, ob es gehängt wird, indem ich die Eigenschaft Enable oder Visible festlege. Kennen Sie Umstände, die die Anwendung, die diese Eigenschaften aufruft, möglicherweise von einem Control.Invoke austeilen?

    
Daniel Peñalba 25.02.2011, 15:45
quelle

5 Antworten

15

Beachten Sie, dass Control.Invoke synchron ist, so dass auf EnableBackControl() gewartet wird. Verwenden Sie Control.BeginInvoke , das Sie "feuern und vergessen" können.

Siehe diese Antwort: Was ist der Unterschied zwischen Invoke ()? und BeginInvoke ()

    
bentsai 25.02.2011, 15:55
quelle
7

Ich habe Probleme bei der Ausführung von .Invoke auf einem Hintergrund-Thread, während mein Haupt-Thread immer noch beschäftigt ist - das gibt den Eindruck, dass die App hängt, weil die .Invoke nur dort sitzt und auf die wartet Haupt-Thread um zu antworten, dass es aufpasst. Mögliche Ursachen:

  • Ihr Haupt-Thread ist blockiert und wartet auf etwas
  • Ihr Hauptformular hat derzeit einen modalen Dialog, so dass neue Anfragen nicht abgehört werden
  • Ihr Haupt-Thread dreht sich, prüft ständig, ob etwas fertig ist oder macht neue Arbeit. In meinem Fall verbrachte der Hauptthread die erste Minute damit, Hintergrundthreads in einer engen Schleife zu drehen, so dass er nicht nach irgendwelchen .Invoke-Anfragen von Hintergrundthreads lauschte.

Wenn Sie den Debugger anhängen, sollten Sie besonders darauf achten, was Ihr Haupt-MessagePump-Thread macht - ich vermute, dass der Mangel an Aufmerksamkeit die Ursache Ihres Problems ist. Wenn Sie feststellen, dass es in Ihrem Hauptthread eine enge Schleife gibt, die nicht reagiert, fügen Sie .DoEvents in die Schleife ein, wodurch die Ausführung angehalten wird und der Hauptthread gezwungen wird, die Nachrichtenpumpe zu leeren und ausstehende Anforderungen weiterzuleiten.

    
SqlRyan 25.02.2011 16:28
quelle
3

Führen Sie das Debugging aus, lassen Sie die App hängen und pausieren Sie das Debugging in Visual Studio und überprüfen Sie die Threads.

    
Andrey 25.02.2011 15:46
quelle
0

Was ich entdeckt habe, ist, dass das eigentliche Zeichnen / Malen von Steuerelementen ziemlich langsam sein kann, besonders wenn Sie viele davon haben und / oder eine doppelte Pufferung für eine sanfte Aktualisierung verwenden. Ich habe BeginInvoke verwendet, um ein ListView-Steuerelement aus Daten zu aktualisieren, die ich von einem Socket empfangen habe. Manchmal waren die Updates so schnell, dass es die App einfror. Ich löste dies, indem ich alles, was ich in den Async-Sockets erhielt, in eine Warteschlange schrieb und dann in einem separaten Thread die Daten löschte und BeginUpdate und EndUpdate in der ListView und Doing verwendete alle ausstehenden Updates dazwischen. Dies schnitt eine Menge extra Nachzeichnen aus und machte die App viel ansprechender.

    
Steed 10.10.2012 21:17
quelle
0

Sie müssen BeginInvoke inested Invoke verwenden, siehe Link "     

alireza amini 13.07.2015 07:57
quelle

Tags und Links