ホームページ >バックエンド開発 >C++ >非同期操作で再入可能でタスクのシーケンスを維持するにはどうすればよいですか?

非同期操作で再入可能でタスクのシーケンスを維持するにはどうすればよいですか?

Susan Sarandon
Susan Sarandonオリジナル
2024-12-28 17:02:15871ブラウズ

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;
    }
}

更新Output

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

Extensions

このアプローチでは、共有状態を保護するロックを実装することで、スレッド セーフなどの追加の改善が可能になります。さらに、タスクの中断を処理するために、キャンセル/再起動ロジックを組み込むことができます。

以上が非同期操作で再入可能でタスクのシーケンスを維持するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。