Ich benutze BackgroundWorker
die meiste Zeit in den Win-Form-Apps, um den Fortschritt zu zeigen, wie ich Daten bekomme. Ich war unter der Annahme, dass Work_completed
garantiert auf dem Haupt-UI-Thread ausgeführt wird, aber es ist nicht. Wenn wir einen Thread erstellen und den worker.RunWorkerAsync
darin aufrufen, bricht es ab, wenn wir versuchen, ein GUI-Steuerelement zu aktualisieren. Hier ein Beispiel:BackgroundWorkerThread Zugriff in einem Thread
private void StartButton_Click(object sender, EventArgs e)
{
Thread thread1 = new Thread(new ThreadStart(PerformWorkerTask));
_worker = new BackgroundWorker();
thread1.Start();
}
public void PerformWorkerTask()
{
_worker.DoWork += delegate
{
for (int i = 0; i < 10; i++)
{
Thread.Sleep(100);
}
};
_worker.RunWorkerCompleted += delegate
{
// this throws exception
MessageLabel.Text = "Completed";
};
_worker.RunWorkerAsync();
}
Wie können wir in diesem Fall Hintergrundarbeiter arbeiten lassen?
es hier scheinen slike thread1 ist ohne Grund geschaffen, aber es verwendet wird, nur einen Fall dar, in dem Hintergrundarbeiter wird von einem Nicht-GUI-Thread aufgerufen. – Sheraz
Gibt es keinen generischen Ansatz, den wir annehmen können? Wie beim Schreiben einer generischen Komponente, die es uns erlaubt, die GUI unabhängig von einem Thread zu aktualisieren, ist sie bereits ausgeführt. – Sheraz
Leider nein. Wenn Sie direkt auf die Steuerelemente zugreifen, müssen Sie sie nur über ihren UI-Thread ändern. Sie können in Betracht ziehen, den Nicht-UI-Thread als BackgroundWorker auszuführen und Ereignisse durch die UI zu leiten, um eine Synchronisation ohne explizites Aufrufen von Control.Invoke zu erreichen, aber am Ende geht alles durch Control.Invoke, wenn es von einem anderen Thread kommt. –