2017-02-08 2 views
0

Ich habe einen Consumer-Thread, der einige Worker-Threads erstellt. Diese Threads müssen zwischen aktiven und wartenden Zuständen wechseln. Wenn sich alle Worker-Threads in den Wartestatus befinden, bedeutet dies, dass der aktuelle Job abgeschlossen ist. Wie kann ich den Consumer-Thread warten lassen, bis alle Worker-Threads im Wartezustand sind? Ich möchte ein Verhalten, das Thread.Join() in allen Worker-Threads sehr ähnelt, möchte jedoch, dass die Threads für den nächsten Job weiter ausgeführt werden. Ich kann keine neuen Threads erstellen, da sich die Jobs in einer engen Schleife befinden und das Erstellen neuer Threads kostspielig ist.Wie kann ich einen Thread warten, bis ein anderer Thread wartet (C#)

+1

Müssen Sie explizite Worker-Threads verwenden? Können Sie diese nicht als [Tasks] (https://msdn.microsoft.com/en-us/library/system.threading.tasks.task (v = vs.110) .aspx) darstellen? Verwenden Sie dann [Task.WhenAll] (https://msdn.microsoft.com/en-us/library/system.threading.tasks.task.whenall (v = vs.110) .aspx), um zu überprüfen, ob alle Aufgaben abgeschlossen sind . Wenn Sie Threads verwenden müssen, sehen Sie sich [AutoResetEvents] (https://msdn.microsoft.com/en-us/library/system.threading.autoresetevent (v = vs.110) .aspx) und [WaitHandle an .WaitAll] (https://msdn.microsoft.com/en-us/library/system.threading.waithandle.waitall (v = vs.110) .aspx). –

+0

Ja, Aufgaben könnten besser funktionieren. Ich war mir nicht so sicher, ob die .net-Version, die ich benutzte, Tasks hatte. Vielleicht ist es falsch, die Aufgaben in einer engen Schleife zu erstellen, weil ich Mono auf Xamarin verwende und der Garbage Collector nicht sehr gut ist. – evg02gsa3

Antwort

3

Soweit ich weiß, gibt es keinen Mechanismus, um zu tun, was Sie wünschen. (Thread.Join, aber da Sie nicht blockieren können, ist keine Option)

Aus den Informationen, die Sie zur Verfügung gestellt, es klingt wie Sie wirklich eine Zustandsmaschine, nur über mehrere Threads.

Ich würde eine Singleton erstellen und diese als eine Zustandsmaschine haben. Threads könnten dem Singleton dort Status signalisieren.

Es klingt wie Sie eine unbestimmte Anzahl von Threads haben, so dass Sie den Status von jedem in einer Sammlung setzen müssen. Ich würde hier Thread Safe Collections suchen, um das richtige zu finden, wie Sie Ihre Statusinformationen speichern möchten.

Hoffe, das hilft.

3

Entschuldigung für die kurze Antwort (kann später erweitern), aber Sie wahrscheinlich die WaitHandle.WaitAll Methode, kombiniert mit einer ManualResetEvent. Sie würden Ihre ManualResetEvent Objekte in jedem Worker-Thread bei ihrer Erstellung übergeben, sie signalisieren, wenn sie inaktiv werden, und die gesamte Gruppe von Handles in die WaitHandle.WaitAll-Methode übergeben, um den Beobachtungs-Thread nach Abschluss zu wecken. Sie können auch die Timeout-Funktion dieser Methode verwenden, wenn Sie während des Wartens regelmäßig eine Art von Task ausführen oder eine Operation ausführen möchten, wenn der Task zu lange dauert.

Beachten Sie, dass wenn Ihre Worker-Threads beendet werden sollen, wenn der Vorgang abgeschlossen ist (war nicht ganz klar, wenn dies der Fall ist), es besser sein könnte, sie als Aufgaben zu erstellen und stattdessen Task.WaitAll verwenden.

Bearbeiten: Bei einem schnellen erneuten Lesen klingt es so, als ob Sie Aufgaben verwenden möchten, anstatt zu versuchen, vollständige Worker-Threads wiederzuverwenden. Aufgaben verwenden Threads, die aus dem Thread-Pool zugewiesen wurden, wodurch der Thread-Erstellungs-Overhead beseitigt wird, um den Sie sich Sorgen gemacht haben, da die Threads (im Allgemeinen) bereit sind und auf Arbeit warten. Sie können einfach jede Aufgabe spawnen und darauf warten, dass alle fertig sind.

Verwandte Themen