Ich habe gerade die Antworten gelesen und es scheint ein sehr heißes Thema zu sein. Ich bin derzeit mit .NET 3.5 SP1 und Windows Forms.
Die bekannte Formel, die in den vorangegangenen Antworten ausführlich beschrieben wurde und die sich auf die InvokeRequired Die Eigenschaft deckt die meisten Fälle ab, aber nicht den gesamten Pool.
Was wäre, wenn die Handgriff noch nicht erstellt worden ist?
El InvokeRequired Eigentum, wie beschrieben hier (Control.InvokeRequired-Eigenschaftsreferenz auf MSDN) gibt true zurück, wenn der Aufruf von einem Thread aus erfolgte, der nicht der GUI-Thread ist, false entweder, wenn der Aufruf vom GUI-Thread aus erfolgte, oder wenn die Handgriff wurde noch nicht erstellt.
Eine Ausnahme kann auftreten, wenn Sie ein modales Formular in einem anderen Thread anzeigen und aktualisieren lassen möchten. Da Sie möchten, dass das Formular modal angezeigt wird, könnten Sie Folgendes tun:
private MyForm _gui;
public void StartToDoThings()
{
_gui = new MyForm();
Thread thread = new Thread(SomeDelegate);
thread.Start();
_gui.ShowDialog();
}
Und der Delegierte kann ein Label auf der GUI aktualisieren:
private void SomeDelegate()
{
// Operations that can take a variable amount of time, even no time
//... then you update the GUI
if(_gui.InvokeRequired)
_gui.Invoke((Action)delegate { _gui.Label1.Text = "Done!"; });
else
_gui.Label1.Text = "Done!";
}
Dies kann zu einer InvalidOperationException wenn die Operationen vor der Aktualisierung des Etiketts "weniger Zeit in Anspruch nehmen" (lesen Sie es und interpretieren Sie es als Vereinfachung) als die Zeit, die der GUI-Thread benötigt, um die Formular 's Handgriff . Dies geschieht innerhalb der ShowDialog() Methode.
Sie sollten auch prüfen, ob die Handgriff wie diese:
private void SomeDelegate()
{
// Operations that can take a variable amount of time, even no time
//... then you update the GUI
if(_gui.IsHandleCreated) // <---- ADDED
if(_gui.InvokeRequired)
_gui.Invoke((Action)delegate { _gui.Label1.Text = "Done!"; });
else
_gui.Label1.Text = "Done!";
}
Sie können die auszuführende Operation behandeln, wenn die Handgriff ist noch nicht erstellt worden: Sie können die GUI-Aktualisierung einfach ignorieren (wie im obigen Code gezeigt) oder Sie können warten (was riskanter ist). Damit sollte die Frage beantwortet sein.
Optionales Material: Persönlich habe ich mir das Folgende ausgedacht:
public class ThreadSafeGuiCommand
{
private const int SLEEPING_STEP = 100;
private readonly int _totalTimeout;
private int _timeout;
public ThreadSafeGuiCommand(int totalTimeout)
{
_totalTimeout = totalTimeout;
}
public void Execute(Form form, Action guiCommand)
{
_timeout = _totalTimeout;
while (!form.IsHandleCreated)
{
if (_timeout <= 0) return;
Thread.Sleep(SLEEPING_STEP);
_timeout -= SLEEPING_STEP;
}
if (form.InvokeRequired)
form.Invoke(guiCommand);
else
guiCommand();
}
}
Ich füttere meine Formulare, die von einem anderen Thread aktualisiert werden, mit einer Instanz von diesem ThreadSafeGuiCommand , und ich definiere Methoden, die die GUI (in meinem Formular) wie folgt aktualisieren:
public void SetLabeTextTo(string value)
{
_threadSafeGuiCommand.Execute(this, delegate { Label1.Text = value; });
}
Auf diese Weise bin ich ziemlich sicher, dass meine GUI aktualisiert wird, unabhängig davon, welcher Thread den Aufruf tätigt, wobei optional eine genau definierte Zeitspanne (der Timeout) abgewartet wird.
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
Vielleicht ein bisschen spät: codeproject.com/KB/cs/Threadsafe_formupdating.aspx
4 Stimmen
Siehe die Antwort für .NET 4.5 und C# 5.0: stackoverflow.com/a/18033198/2042090
5 Stimmen
Diese Frage bezieht sich nicht auf Gtk# GUI. Für Gtk# siehe diese y diese Antwort.
3 Stimmen
Vorsicht: Die Antworten auf diese Frage sind jetzt ein unübersichtliches Durcheinander von OT ("hier ist, was ich für meine WPF-Anwendung getan habe") und historischen .NET 2.0-Artefakten.
0 Stimmen
Ähnlicher Beitrag - GUI-Aktualisierung vom UI-Thread aus erzwingen