任务排序和重入
在任务到达速度快于处理速度并且可能依赖于先前结果的情况下,对任务进行排序变得至关重要。当需要重新进入时,这个挑战会变得更加复杂。
问题陈述
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中文网其他相关文章!