Aufgabensequenzierung und Wiedereintritt
In Szenarien, in denen Aufgaben schneller eintreffen können als verarbeitet werden und möglicherweise von vorherigen Ergebnissen abhängen, werden Aufgaben sequenziert wird entscheidend. Diese Herausforderung verschärft sich, wenn ein erneuter Eintritt erforderlich ist.
Problemstellung
Ein UI-Befehlshandler kann Befehle synchron oder asynchron verarbeiten. Befehle können mit einer Geschwindigkeit eintreffen, die die Verarbeitungsgeschwindigkeit übersteigt, was eine Warteschlangenbildung und sequentielle Verarbeitung erforderlich macht. Das Ergebnis jeder neuen Aufgabe kann von ihrem Vorgänger abhängen. Während eine Stornierung der Einfachheit halber ausgeschlossen ist, muss ein erneuter Eintritt unterstützt werden.
Erster Ansatz
In einer einfachen Konsolen-App verwaltet eine AsyncOp-Klasse die Aufgabensequenzierung. Jede Aufgabe wird als Fortsetzung der vorherigen behandelt, um sicherzustellen, dass Abhängigkeiten erfüllt sind. Wenn jedoch Wiedereintritt eingeführt wird, bricht die Logik zusammen.
Synchronisierte Lösung
Um dieses Problem zu beheben, werden Aufgaben manuell erstellt, ohne sie zunächst zu planen. Stattdessen wird „Task.Factory.StartNew“ verwendet, um die Aufgaben synchron auszuführen und ihre Ausführung zu verhindern, bis die Wrapper-Aufgabe bereit ist. Dadurch wird sichergestellt, dass die Reihenfolge eingehalten wird.
Code-Implementierung
class AsyncOp<T> { Task<T> _pending = Task.FromResult(default(T)); public Task<T> CurrentTask => _pending; public Task<T> RunAsync(Func<Task<T>> handler, bool useSynchronizationContext = false) { var pending = _pending; var wrapper = async () => { var prevResult = await pending; Console.WriteLine($"\nprev task result: {prevResult}"); return await handler(); }; var task = new Task<Task<T>>(wrapper); var inner = task.Unwrap(); _pending = inner; task.RunSynchronously(useSynchronizationContext ? TaskScheduler.FromCurrentSynchronizationContext() : TaskScheduler.Current); return inner; } }
Aktualisierte Ausgabe
Test #1... prev task result: 0 this task arg: 1000 prev task result: 1000 this task arg: 900 prev task result: 900 this task arg: 800 Press any key to continue to test #2... prev task result: 800 this task arg: 100 prev task result: 100 this task arg: 200
Erweiterungen
Dieser Ansatz ermöglicht zusätzliche Verbesserungen wie Thread-Sicherheit durch die Implementierung von a Sperre zum Schutz des gemeinsamen Zustands. Darüber hinaus kann eine Abbruch-/Neustartlogik integriert werden, um Aufgabenunterbrechungen zu bewältigen.
Das obige ist der detaillierte Inhalt vonWie kann die Aufgabensequenzierung mit Wiedereintritt in asynchronen Vorgängen aufrechterhalten werden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!