任務排序和重入
在任務到達速度快於處理速度並且可能依賴於先前結果的情況下,對任務進行排序變得至關重要。當需要重新進入時,這個挑戰會變得更加複雜。
問題陳述
UI 指令處理程序可以同步或非同步處理指令。命令到達的速度可能超過處理速度,因此需要排隊和順序處理。每個新任務的結果可能取決於其前一個任務。雖然為了簡單起見排除了取消,但必須支援重入。
初始方法
在基本控制台應用程式中,AsyncOp 類別管理任務排序。每項任務都被視為前一項任務的延續,確保滿足依賴關係。然而,當引入重入時,邏輯就會崩潰。
同步解決方案
為了解決這個問題,任務是手動建構的,而不是最初調度它們。相反,「Task.Factory.StartNew」用於同步運行任務,防止它們在包裝器任務準備就緒之前執行。這可確保維持順序。
程式碼實作
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; } }
更新的輸出
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
擴充
這種方法可以實現額外的改進例如透過實作鎖定來保護共用狀態的執行緒安全性。此外,可以合併取消/重新啟動邏輯來處理任務中斷。
以上是在非同步操作中如何透過重入來維持任務排序?的詳細內容。更多資訊請關注PHP中文網其他相關文章!