2009-03-05 6 views
0

OK, bitte ignorieren Sie, was vorher gegangen ist. Ich bekomme die Fehler nicht mehr, daher scheint mein Problem darin zu bestehen, ein Diagramm zu aktualisieren, wenn ich die Werte ändere, an die das Diagramm gebunden ist.Control.Refresh() über Threads

// Disregard unten hier

Hallo alle. Ich habe eine WinForms-Anwendung, die ein Panel hat, panel1. Ein Hintergrund-Thread erstellt einige andere Steuerelemente, die dann wie

so zu panel1 hinzukommen
panel1.Controls.AddRange(myArrayOfControls); 

Dies funktioniert gut und ich kann meine Kontrollen zu sehen bekommen hinzugefügt. Wenn jedoch neue Daten in einem anderen Thread eingehen, aktualisiere ich die Werte in den übergeordneten Objekten der Steuerelemente und benötige dann Refresh(), damit die Anzeige mit den neuen Werten aktualisiert wird. Wenn Sie in einem der beiden Kontexte Refresh() aufrufen, verursacht der Thread, in dem die Daten eingehen, oder die Objekte, die die aktualisierten Daten empfangen, eine InvalidOperation-Ausnahme, da Invoke erforderlich ist. Ich habe versucht, Invoke in meinen Modellobjekten und auch in dem Thread zu verwenden, in dem die Daten eingehen, und scheint den Fehler nicht zu erschüttern.

Wenn jemand eine Anleitung hat, würde ich es sehr schätzen.

UPDATE: Hier ist ein wenig mehr Info. Ich dachte nicht, dass es das erfordern würde, aber ich lag falsch. :)

Ich habe eine Objektklasse MyObject. Diese MyObject-Klasse wird in einem Thread namens topologyThread erstellt. Daten kommen auf dataThread. Instanzen von MyObject verfügen über eine Panel-Instanzvariable, und das Panel verfügt über untergeordnete Steuerelemente einschließlich zweier Diagramme aus dem System.Windows.Forms.DataVisualization.Charting-Namespace. Wenn Daten in dataThread eingehen, aktualisiere ich die entsprechenden Datenwerte in den MyObject-Objekten und muss dann die Diagramme aktualisieren, um die aktualisierten Daten anzuzeigen.

Ich weiß, dass die Daten in Ordnung sind. In meiner MyObject-Klasse protokolliere ich die neuen Werte in Console im Setter für die Eigenschaft und sehe, wie die neuen Werte angezeigt werden.

Antwort

6

Sie müssen beide Vorgänge (Aktualisieren und Aktualisieren des übergeordneten Objekts des Steuerelements) über den Hauptthread der Benutzeroberfläche ausführen. Wenn Sie ein Steuerelement aus einem Hintergrundthread ändern und keine Ausnahme erhalten, die Pech hat, weil es definitiv ein Fehler ist.

Der beste Weg, dies zu tun ist

theControl.Invoke(new MethodInvoker(MyUpdateMethod)); 

Wenn Sie eine Probe haben zu verwenden, wie das Update abgeschlossen ist, können wir eine bessere Probe geben, wie es richtig rufen aus dem Hintergrund-Thread.

0

JaredPar's Antwort ist gut. In einigen Fällen kann es zu Problemen kommen (insbesondere, wenn die Methode aufgerufen wird, bevor das Formular fertiggestellt ist). Hier ist eine etwas robustere Implementierung (mit Erweiterungsmethoden)

public static class ControlInvokeExtensions 
{ 
    public static void InvokeOnHostThread(Control host, MethodInvoker method) 
    { 
     if (IsHandleCreated) 
      Invoke(new EventHandler(delegate { method(); })); 
     else 
      method(); 
    } 
} 

jetzt können Sie es nennen diese Art und Weise

panel1.InvokeOnHostThread(() => panel1.Controls.AddRange(myArrayOfControls)); 

oder wenn Sie in Form sind:

InvokeOnHostThread(() => panel1.Controls.AddRange(myArrayOfControls)); 
1

JaredPar ist eine ziemlich gute Antwort. Ich möchte hinzufügen, ein bisschen wie der Code funktioniert.

Mit Windows-Formularen können Sie mit dem UI-Thread von anderen Threads sprechen. Dies ist in allen Fällen eine sehr schlechte Übung.

Der Haken ist, dass wenn Sie es tun, ist es schwer zu fangen, weil manchmal die Benutzeroberfläche als ob nichts falsch ist. Das Element wird hinzugefügt oder geändert und die Benutzeroberfläche spiegelt die Änderungen wider. In anderen Fällen wird derselbe Code jedoch nicht ausgeführt.

Das ist der Haken beim Berühren der Benutzeroberfläche von einem anderen Thread als dem UI-Thread. Das Ergebnis ist inkonsistent und deshalb ist sehr schlechte Praxis.

Gott ich wünschte, ich könnte kommentieren. :)

+1

+1, jetzt bist du 10 Wiederholungen näher dran zu kommentieren. :) –

Verwandte Themen