Aufgabensequenzierung und Wiedereintritt: Sequentielle Befehle in einer Multithread-Umgebung verwalten
In realen Softwareanwendungen kommt es häufig vor, dass Szenarien auftreten bei denen Aufgaben nacheinander bearbeitet werden und ihre Ausführungsreihenfolge von entscheidender Bedeutung ist. Die Aufgabensequenzierung wird noch komplexer, wenn Aufgaben möglicherweise schneller eintreffen, als sie verarbeitet werden können, und sie wiedereintretend sind, was bedeutet, dass sie gleichzeitig in sich selbst ausgeführt werden können.
Stellen Sie sich das folgende Szenario vor:
Traditionell kann das Sync-or-Async-Problem durch die Verwendung der Task.Factory.StartNew-Methode mit der behoben werden TaskScheduler.FromCurrentSynchronizationContext()-Parameter zum Erzwingen der asynchronen Ausführung. Dieser Ansatz ist jedoch möglicherweise nicht ideal, wenn die Befehlshandler so konzipiert sind, dass sie intern synchron ausgeführt werden.
Um dieser Herausforderung zu begegnen, kann eine benutzerdefinierte Klasse namens AsyncOp implementiert werden. AsyncOp kümmert sich um die Aufgabensequenzierung und die Wiedereintrittsanforderungen. Hier ist eine aktualisierte Version der Klasse AsyncOp mit zusätzlichen Funktionen:
class AsyncOp<T> { private Task<T> _pending = Task.FromResult(default(T)); private readonly object _lock = new object(); public Task<T> CurrentTask => _pending; public Task<T> RunAsync(Func<Task<T>> handler, bool useSynchronizationContext = false) { Task<Task<T>> task = null; lock (_lock) { var pending = _pending; Task<T> wrapper = async () => { // Await the previous task T prevResult = await pending; Console.WriteLine("\nPrevious task result: " + prevResult); // Start and await the handler return await handler(); }; task = new Task<Task<T>>(wrapper); var inner = task.Unwrap(); _pending = inner; } task.RunSynchronously(useSynchronizationContext ? TaskScheduler.FromCurrentSynchronizationContext() : TaskScheduler.Current); return inner; } public async Task HandleCancelAsync() { Task pendingCopy = null; lock (_lock) { pendingCopy = _pending; } // Cancel previous tasks as long as they are not the latest (current) task if (pendingCopy != CurrentTask && pendingCopy != null) await ((Task)pendingCopy).ContinueWith(t => t.Dispose()); } public async Task HandleRestartAsync() { Task pendingCopy = null; lock (_lock) { pendingCopy = _pending; if (pendingCopy.IsCompleted && pendingCopy != null) _pending = Task.FromResult(default(T)); } } }
Diese aktualisierte Version bietet die folgenden Verbesserungen:
Mit dieser aktualisierten AsyncOp-Klasse kann der in der Frage bereitgestellte Beispielcode wie folgt umgeschrieben werden:
using System; using System.Threading.Tasks; namespace ConsoleApp { class Program { static async Task Main(string[] args) { var asyncOp = new AsyncOp<int>(); Func<int, Task<int>> handleAsync = async (arg) => { Console.WriteLine("This task arg: " + arg); // Delay the execution await Task.Delay(arg); return await Task.FromResult(arg); }; Console.WriteLine("Test #1..."); asyncOp.RunAsync(() => handleAsync(1000)); asyncOp.RunAsync(() => handleAsync(900)); asyncOp.RunAsync(() => handleAsync(800)); await asyncOp.CurrentTask; Console.WriteLine("\nPress any key to continue to test #2..."); Console.ReadLine(); asyncOp.RunAsync(() => { var handle100Task = handleAsync(100); asyncOp.RunAsync(() => handleAsync(200), true); return handle100Task; }); await asyncOp.CurrentTask; Console.WriteLine("\nPress any key to exit..."); Console.ReadKey(); } } }
In dieser aktualisierten Version wird die handleAsync-Aufgabe mithilfe der Task.Delay-Methode zur asynchronen Ausführung gezwungen, um die Wiedereintrittsfähigkeiten von zu demonstrieren AsyncOp.
Diese Lösung bietet eine robuste und effiziente Möglichkeit, die Reihenfolge und den Wiedereintritt von Aufgaben zu verwalten und sicherzustellen, dass Befehle in der gewünschten Reihenfolge ausgeführt werden, unabhängig von der Geschwindigkeit, mit der sie eintreffen.
Das obige ist der detaillierte Inhalt vonWie kann AsyncOp die Aufgabensequenzierung und den Wiedereintritt in Multithread-Umgebungen effizient verwalten?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!