首页 > 后端开发 > C++ > 异步操作中如何通过重入来维持任务排序?

异步操作中如何通过重入来维持任务排序?

Susan Sarandon
发布: 2024-12-28 17:02:15
原创
868 人浏览过

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中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板