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

13voto

A. Zalonis Punkte 1579

Sie müssen invoke und delegate verwenden

private delegate void MyLabelDelegate();
label1.Invoke( new MyLabelDelegate(){ label1.Text += 1; });

13voto

Versuchen Sie, das Etikett wie folgt zu aktualisieren

public static class ExtensionMethods
{
    private static Action EmptyDelegate = delegate() { };

    public static void Refresh(this UIElement uiElement)
    {
        uiElement.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate);
    }
}

0 Stimmen

Ist es für Windows-Formulare ?

12voto

Basheer AL-MOMANI Punkte 13273

Der einfachste Weg in WPF-Anwendungen ist:

this.Dispatcher.Invoke((Action)(() =>
{
    // This refers to a form in a WPF application 
    val1 = textBox.Text; // Access the UI 
}));

4 Stimmen

Dies ist richtig, wenn Sie eine WPF-Anwendung verwenden. Aber er verwendet Windows Forms.

0 Stimmen

Sie können den Dispatcher auch in einer Winforms-Anwendung verwenden. stackoverflow.com/questions/303116/

10voto

nan Punkte 18346

Wenn Sie im UI-Thread sind, könnten Sie ihn nach seinem Synchronisationskontext-Taskplaner fragen. Er würde Ihnen eine TaskScheduler die alles auf dem UI-Thread plant.

Dann können Sie Ihre Aufgaben so verketten, dass, wenn das Ergebnis fertig ist, eine andere Aufgabe (die auf dem UI-Thread geplant ist) es auswählt und einem Etikett zuordnet.

public partial class MyForm : Form
{
  private readonly TaskScheduler _uiTaskScheduler;
  public MyForm()
  {
    InitializeComponent();
    _uiTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
  }

  private void buttonRunAsyncOperation_Click(object sender, EventArgs e)
  {
    RunAsyncOperation();
  }

  private void RunAsyncOperation()
  {
    var task = new Task<string>(LengthyComputation);
    task.ContinueWith(antecedent =>
                         UpdateResultLabel(antecedent.Result), _uiTaskScheduler);
    task.Start();
  }

  private string LengthyComputation()
  {
    Thread.Sleep(3000);
    return "47";
  }

  private void UpdateResultLabel(string text)
  {
    labelResult.Text = text;
  }
}

Dies funktioniert für Tasks (nicht Threads), die die Bevorzugte Art, nebenläufigen Code zu schreiben .

1 Stimmen

Aufruf von Task.Start ist in der Regel keine gute Praxis blogs.msdn.com/b/pfxteam/archive/2012/01/14/10256832.aspx

9voto

Da Xiong Punkte 135

Greifen Sie zum Beispiel auf ein Steuerelement zu, das sich nicht im aktuellen Thread befindet:

Speed_Threshold = 30;
textOutput.Invoke(new EventHandler(delegate
{
    lblThreshold.Text = Speed_Threshold.ToString();
}));

Dort werden die lblThreshold ist ein Label und Speed_Threshold ist eine globale Variable.

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