首頁 >後端開發 >C++ >在非同步操作中如何透過重入來維持任務排序?

在非同步操作中如何透過重入來維持任務排序?

Susan Sarandon
Susan Sarandon原創
2024-12-28 17:02:15887瀏覽

How Can Task Sequencing Be Maintained with Re-Entrancy in Asynchronous Operations?

任務排序和重入

在任務到達速度快於處理速度並且可能依賴於先前結果的情況下,對任務進行排序變得至關重要。當需要重新進入時,這個挑戰會變得更加複雜。

問題陳述

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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn