Ich habe ein bisschen Code, den ich in einem anderen Thread als der GUI ausführen muss, da das Formular derzeit einfriert, während der Code ausgeführt wird (ca. 10 Sekunden).
Angenommen, ich habe noch nie einen neuen Thread erstellt. Was ist ein einfaches / grundlegendes Beispiel dafür, wie dies in C # und unter Verwendung von .NET Framework 2.0 oder höher durchgeführt wird?
c#
.net
multithreading
p.campbell
quelle
quelle
Antworten:
Ein guter Ort, um mit dem Lesen zu beginnen, ist Joe Albahari .
Wenn Sie einen eigenen Thread erstellen möchten, ist dies so einfach wie möglich:
quelle
IsBackground
auf true. Es macht wahrscheinlich nicht das, was Sie denken. Konfigurieren Sie, ob der Thread beendet wird, wenn alle Vordergrund-Threads gestorben sind, oder ob der Thread die Anwendung am Leben erhält. Wenn Sie nicht möchten, dass Ihr Thread während der Ausführung beendet wird, setzen Sie nichtIsBackground
auf true.BackgroundWorker
scheint die beste Wahl für Sie zu sein.Hier ist mein minimales Beispiel. Nachdem Sie auf die Schaltfläche geklickt haben, beginnt der Hintergrundarbeiter mit der Arbeit im Hintergrundthread und meldet gleichzeitig den Fortschritt. Es wird auch nach Abschluss der Arbeiten berichtet.
Hinweis:
ProgressChanged
oder derRunWorkerCompleted
Handler zu aktualisieren . Das Aktualisieren der GUI vonDoWork
führt jedoch dazuInvalidOperationException
.quelle
Das ThreadPool.QueueUserWorkItem ist ziemlich ideal für etwas Einfaches. Die einzige Einschränkung ist der Zugriff auf ein Steuerelement vom anderen Thread.
quelle
Schnell und schmutzig, aber es wird funktionieren:
Oben verwenden:
einfacher Code:
Ich habe dies zum Beispiel in eine neue Konsolenanwendung geworfen
quelle
Hier ist eine weitere Option:
quelle
Versuchen Sie es mit der BackgroundWorker- Klasse. Sie geben ihm Delegierte, was ausgeführt werden soll, und werden benachrichtigt, wenn die Arbeit beendet ist. Auf der MSDN-Seite, auf die ich verlinkt habe, befindet sich ein Beispiel.
quelle
Wenn Sie einen Wert erhalten möchten:
quelle
Fügen Sie diesen Code in eine Funktion ein (den Code, der nicht im selben Thread wie die GUI ausgeführt werden kann), und geben Sie Folgendes ein, um die Ausführung dieses Codes auszulösen.
Thread myThread= new Thread(nameOfFunction);
workerThread.Start();
Wenn Sie die Startfunktion für das Thread-Objekt aufrufen, wird Ihr Funktionsaufruf in einem neuen Thread ausgeführt.
quelle
nameOfFunction
im Hintergrund und nicht im aktuellen GUI-Thread ausgeführt. DieIsBackground
Eigenschaft bestimmt, ob der Thread die Anwendung am Leben erhältHier erfahren Sie, wie Sie Threads mit einer progressBar verwenden können. Dies dient nur dazu, die Funktionsweise der Threads zu verstehen. In der Form gibt es drei progressBar- und vier Schaltflächen:
quelle
Charles, dein Code (oben) ist nicht korrekt. Sie müssen nicht warten, bis der Vorgang abgeschlossen ist. EndInvoke wird blockiert, bis das WaitHandle signalisiert wird.
Wenn Sie bis zur Fertigstellung blockieren möchten, müssen Sie einfach
oder alternativ
Aber was bringt es, wenn Sie blockieren, wenn Sie blockieren? Sie können auch einfach einen synchronen Anruf verwenden. Eine bessere Wette wäre, ein Lambda nicht zu blockieren und zur Bereinigung weiterzugeben:
Eine Sache im Auge zu behalten ist , dass Sie müssen EndInvoke nennen. Viele Leute vergessen dies und verlieren am Ende das WaitHandle, da die meisten asynchronen Implementierungen das Waithandle in EndInvoke freigeben.
quelle
Wenn Sie das rohe Thread-Objekt verwenden möchten, müssen Sie IsBackground mindestens auf true setzen und das Threading Apartment-Modell (wahrscheinlich STA) festlegen.
Ich würde die BackgroundWorker-Klasse empfehlen, wenn Sie eine UI-Interaktion benötigen.
quelle
Eine weitere Option, die Delegaten und den Thread-Pool verwendet ...
Angenommen, 'GetEnergyUsage' ist eine Methode, die eine DateTime und eine andere DateTime als Eingabeargumente verwendet und eine Int ...
quelle
int usageCnt = nrgDel.Invoke(lastRunTime, procDT, null, null);
? Es sieht so aus, als würde der aktuelle Thread ohnehin mit dem Ruhezustand angehalten ... Ich dachte, es hilft nichts beim Einfrieren der GUI, wenn Sie ihn im GUI-ThreadEs gibt viele Möglichkeiten, separate Threads in .Net auszuführen. Jedes hat unterschiedliche Verhaltensweisen. Müssen Sie den Thread nach dem Beenden der GUI weiter ausführen? Müssen Sie Informationen zwischen dem Thread und der GUI weitergeben? Muss der Thread die GUI aktualisieren? Sollte der Thread eine Aufgabe ausführen und dann beenden oder sollte er weiter ausgeführt werden? Die Antworten auf diese Fragen zeigen Ihnen, welche Methode Sie verwenden müssen.
Auf der Code Project-Website finden Sie einen guten Artikel über asynchrone Methoden, in dem die verschiedenen Methoden beschrieben und Beispielcode bereitgestellt werden.
Beachten Sie, dass dieser Artikel geschrieben wurde, bevor das asynchrone / wartende Muster und die Task Parallel Library in .NET eingeführt wurden.
quelle
Gewusst wie: Verwenden Sie einen Hintergrund-Thread, um nach Dateien zu suchen
Sie müssen beim Zugriff von anderen Threads auf GUI-spezifische Inhalte sehr vorsichtig sein (dies ist bei vielen GUI-Toolkits üblich). Wenn Sie etwas in der GUI über den Verarbeitungsthread aktualisieren möchten, überprüfen Sie diese Antwort , die meiner Meinung nach für WinForms nützlich ist. Für WPF siehe dies (es zeigt, wie man eine Komponente in der UpdateProgress () -Methode berührt, damit sie von anderen Threads aus funktioniert, aber eigentlich gefällt es mir nicht, dass es nicht funktioniert,
CheckAccess()
bevor manBeginInvoke
Dispathcer durchläuft, siehe CheckAccess darin und sucht danach).Ich habe ein .NET-spezifisches Buch zum Thema Threading gesucht und dieses gefunden (kostenlos herunterladbar). Siehe http://www.albahari.com/threading/ , um weitere Informationen darüber.
Ich glaube, Sie werden auf den ersten 20 Seiten finden, was Sie brauchen, um die Ausführung als neuer Thread zu starten, und es gibt noch viel mehr (nicht sicher über GUI-spezifische Snippets, die ich streng spezifisch für das Threading meine). Würde mich freuen zu hören, was die Community über diese Arbeit denkt, denn ich lese diese. Im Moment sah es für mich ziemlich ordentlich aus (um .NET-spezifische Methoden und Typen für das Threading anzuzeigen). Außerdem behandelt es .NET 2.0 (und nicht das alte 1.1), was ich wirklich schätze.
quelle
Ich würde empfehlen, sich Jeff Richters Power Threading Library und speziell den IAsyncEnumerator anzusehen. Schauen Sie sich das Video zu Charlie Calvert an Blog an, in dem Richter einen guten Überblick darüber gibt.
Lassen Sie sich nicht vom Namen abschrecken, da dadurch asynchrone Programmieraufgaben einfacher zu codieren sind.
quelle