Gibt es eine Möglichkeit, einen Delegaten für einen bestimmten Thread auszuführen?
Sprich ich habe:
%Vor%Kann ich einen konsistenten im Hintergrund laufenden Thread haben und meine eigenen Delegierten dazu aufrufen, wann immer ich es brauche. Es muss jedes Mal der gleiche Thread sein.
[Bearbeiten]
Der Grund, warum ich möchte, dass es auf einem dedizierten Thread ist, ist, dass ich beabsichtige, den Delegaten darauf auszuführen und den Thread nach y
Millisekunden anzuhalten und den Thread wieder aufzunehmen, wenn ich einen anderen Delegaten darauf ausführe. Ich sehe, das ist nicht möglich. Ich werde eine Delegatenwarteschlange haben und die Hauptfunktion des Threads lesen und ausführen lassen.
Um es mit einem konkreten Beispiel zu verdeutlichen, habe ich ein Spielsystem mit einer Reihe von Spieler-Threads. Ich möchte, dass jeder Spielerthread Ereignishandler für Spielevents darauf ausführt. Wenn die Event-Handler zu viel Zeit brauchen, würde ich gerne diesen bestimmten Spieler bis zum nächsten Event anhalten können, indem ich seinen Thread aussetze.
Wenn ich also einen dedizierten Thread habe, auf dem ich mehrere Event-Handler ausführen kann, kann ich die KI eines bestimmten Players pausieren, falls es abgehört wird oder zu lange dauert.
Ich denke, die beste Lösung besteht darin, Task
-Objekte zu verwenden und sie in eine StaThreadScheduler führt einen einzelnen Thread aus.
Alternativ können Sie den ActionThread
in Nito.Async verwenden, um einen normalen Thread mit einer integrierten Warteschlange von% zu erstellen. co_de% delegiert.
Jedoch wird keines von beiden direkt ein anderes Bedürfnis ansprechen: die Fähigkeit, eine Aktion "anzuhalten" und mit einer anderen fortzufahren. Dazu müssen Sie während jeder Aktion "Synchronisierungspunkte" streuen und können den Status speichern, erneut in die Warteschlange stellen und mit der nächsten Aktion fortfahren.
All diese Komplexität kommt einem Thread-Scheduling-System sehr nahe. Daher empfehle ich, einen Schritt zurückzutreten und mehr von einem Re-Design zu machen. Sie können jeder Aktion erlauben, in die Warteschlange für Action
gestellt zu werden (ich empfehle, nur ein ThreadPool
-Objekt zu haben). Sie müssen immer noch "Synchronisierungspunkte" streuen, aber anstatt den Status zu speichern und sie neu zu ordnen, müssen Sie sie nur pausieren (blockieren).
Leider ist wirklich nichts eingebaut, um dies auf einem generischen Thread zu tun. Sie können dies erreichen, indem Sie eine Klasse erstellen, die einen Thread umschließt und ISynchonizeInvoke implementiert.
Ein einfacher Ansatz besteht darin, eine Ereignisverarbeitungswarteschlange für den dedizierten Thread zu erstellen, wie LBushkin erwähnt. Ich schlage vor, eine Klasse Queue<Action>
zu verwenden und den Aktionsdelegaten direkt aufzurufen. Sie können die meisten Aufgaben ausführen, die Sie mit anonymen Delegataktionen benötigen.
Zum Schluss, als Warnung, würde ich vorschlagen, dass Sie einen Semaphore oder EventWaitHandle anstelle von Thread.Sleep in Ihrem eigenen Thread verwenden. Es ist definitiv freundlicher als die Hintergrundschleife immer und immer wieder auszuführen, wenn es unnötig ist.
Normalerweise würde ich vorschlagen, nur den Thread-Pool oder BackgroundWorker
class zu verwenden - aber das garantiert nicht, dass Arbeit in einem bestimmten Thread stattfindet. Es ist unklar, warum du dich interessierst, welcher Thread die Arbeiten ausführt, aber angenommen, dass es irgendwie von Bedeutung ist ...
Sie müssten das Delegate
-Objekt durch eine Art von gemeinsam genutztem Speicher wie eine Warteschlange übergeben. Der Hintergrund-Thread müsste diese Warteschlange überwachen, Delegaten davon abziehen, wenn sie existieren, und sie ausführen.
Wenn sich herausstellt, dass der Threadpool für die Ausführung Ihres Codes akzeptabel ist, können Sie immer die Methode BeginInvoke
des Delegaten verwenden:
Für Threads, die Sie erstellen, können Sie den ThreadStart-Delegaten nur angeben, wenn Sie sie erstellen. Es gibt keine Möglichkeit, einen anderen Delegaten in einen erstellten Thread einzufügen. Der Thread-Pool unterscheidet sich dadurch, dass Sie Delegaten an zuvor erstellte Threads senden können, die in Ihrem Namen gestartet werden.
Es ist nicht klar, welches Problem du lösen willst. Was versuchen Sie zu erreichen (oder zu vermeiden), indem Sie versuchen, mehrere Delegaten in einem Thread auszuführen?
Tags und Links c# multithreading delegates