1592 Stimmen

Wie aktualisiere ich die GUI von einem anderen Thread aus?

Welches ist der einfachste Weg, eine Label von einem anderen Thread ?

  • Tengo un Form weiterlaufend thread1 und davon ausgehend eröffne ich ein weiteres Thema ( thread2 ).

  • Während thread2 einige Dateien verarbeitet, würde ich gerne eine Label sur le Form mit dem aktuellen Status von thread2 Arbeit.

Wie könnte ich das tun?

28 Stimmen

Hat .net 2.0+ nicht die BackgroundWorker-Klasse genau für diesen Zweck. Es UI Thread bewusst. 1. Erstellen Sie einen BackgroundWorker 2. Fügen Sie zwei Delegierte hinzu (einen für die Verarbeitung und einen für den Abschluss)

15 Stimmen

4 Stimmen

Siehe die Antwort für .NET 4.5 und C# 5.0: stackoverflow.com/a/18033198/2042090

18voto

Hassan Shouman Punkte 275

Verwenden Sie einfach etwas wie dieses:

 this.Invoke((MethodInvoker)delegate
            {
                progressBar1.Value = e.ProgressPercentage; // runs on UI thread
            });

0 Stimmen

Wenn Sie eine e.ProgressPercentage Sind Sie nicht bereits im UI-Thread der Methode, die Sie hier aufrufen?

0 Stimmen

Das Ereignis ProgressChanged wird auf dem UI-Thread ausgeführt. Das ist eine der Annehmlichkeiten der Verwendung des BackgroundWorkers. Das Completed-Ereignis läuft ebenfalls in der Benutzeroberfläche. Das einzige, was im Nicht-UI-Thread läuft, ist die DoWork-Methode.

16voto

flodis Punkte 915

Und noch eine weitere Gattungsbezeichnung Kontrolle Erweiterung des Ansatzes.

Fügen Sie zunächst eine Erweiterungsmethode für Objekte des Typs Kontrolle

public static void InvokeIfRequired<T>(this T c, Action<T> action) where T : Control
{
    if (c.InvokeRequired)
    {
        c.Invoke(new Action(() => action(c)));
    }
    else
    {
        action(c);
    }
}

und rufen Sie wie folgt von einem anderen Thread aus auf, um auf ein Steuerelement namens object1 im UI-Thread zuzugreifen:

object1.InvokeIfRequired(c => { c.Visible = true; });
object1.InvokeIfRequired(c => { c.Text = "ABC"; });

oder so

object1.InvokeIfRequired(c => 
  { 
      c.Text = "ABC";
      c.Visible = true; 
  }
);

0 Stimmen

Sehr elegant, sehr schön!

0 Stimmen

Ich habe begonnen, c.BeginInvoke für asynchrone Aktualisierungen zu verwenden. Es ist weniger wahrscheinlich, dass es zu Deadlocks kommt, wenn es in einer Kaskade aufgerufen wird.

16voto

Embedd_0913 Punkte 15511

Sie können den bereits existierenden Delegierten verwenden Action :

private void UpdateMethod()
{
    if (InvokeRequired)
    {
        Invoke(new Action(UpdateMethod));
    }
}

16voto

MajesticRa Punkte 12948

Meine Version besteht darin, Folgendes einzufügen eine Zeile eines rekursiven "Mantras":

Für keine Argumente:

    void Aaaaaaa()
    {
        if (InvokeRequired) { Invoke(new Action(Aaaaaaa)); return; } //1 line of mantra

        // Your code!
    }

Für eine Funktion, die Argumente hat:

    void Bbb(int x, string text)
    {
        if (InvokeRequired) { Invoke(new Action<int, string>(Bbb), new[] { x, text }); return; }
        // Your code!
    }

DAS ist es .


Einige Argumente : Normalerweise ist es schlecht für die Lesbarkeit des Codes, {} nach einer if () Anweisung in einer Zeile. Aber in diesem Fall handelt es sich um ein routinemäßiges "Mantra". Die Lesbarkeit des Codes wird nicht beeinträchtigt, wenn diese Methode über das gesamte Projekt hinweg konsistent ist. Und es bewahrt Ihren Code vor Vermüllung (eine Zeile Code anstelle von fünf).

Wie Sie sehen if(InvokeRequired) {something long} Sie wissen einfach, dass "diese Funktion sicher von einem anderen Thread aus aufgerufen werden kann".

15voto

blackmind Punkte 1286

Erstellen Sie eine Klassenvariable:

SynchronizationContext _context;

Legen Sie sie in dem Konstruktor fest, der Ihre Benutzeroberfläche erstellt:

var _context = SynchronizationContext.Current;

Wenn Sie das Etikett aktualisieren möchten:

_context.Send(status =>{
    // UPDATE LABEL
}, null);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X