带任务取消机制的有序任务队列实现方案可行性咨询
带取消等待逻辑的任务队列实现方案可行性咨询
我需要实现一个按顺序执行的任务队列,核心要求是:
- 添加新任务时,立即取消队列中当前正在执行的所有任务
- 新任务必须等被取消的任务完全结束(包括处理取消后的逻辑)后,才能启动执行
举个场景例子:先加入一个耗时5秒的task1,1秒后再加入task2,此时需要先触发task1的取消操作,等task1彻底完成取消流程后,再启动task2。
我基于一段现有代码做了适配,添加了上述取消相关的逻辑,想请教这个方案是否可行:
public sealed class ExecutionQueue { private readonly BlockingCollection<Func<Task>> _queue = new BlockingCollection<Func<Task>>(); private CancellationTokenSource? _cancellationTokenSource; public ExecutionQueue() => Completion = Task.Run(() => ProcessQueueAsync()); public Task Completion { get; } public void Complete() => _queue.CompleteAdding(); private async Task ProcessQueueAsync() { foreach (var value in _queue.GetConsumingEnumerable()) await value(); } public Task Run(Func<CancellationToken, Task> lambda) { if (_cancellationTokenSource != null) { _cancellationTokenSource.Cancel(); _cancellationTokenSource.Dispose(); } _cancellationTokenSource = new CancellationTokenSource(); var tcs = new TaskCompletionSource<object>(); _queue.Add(async () => { try { await lambda(_cancellationTokenSource.Token); tcs.TrySetResult(null); } catch (OperationCanceledException ex) { tcs.TrySetCanceled(ex.CancellationToken); } catch (Exception ex) { tcs.TrySetException(ex); } }, _cancellationTokenSource.Token); return tcs.Task; } }
示例用法:
public partial class MainWindow : Window { private ExecutionQueue _queue = new ExecutionQueue(); public MainWindow() { DataContext = this; InitializeComponent(); } int count = 0; private void Button_Click(object sender, RoutedEventArgs e) { int v = count++; _queue.Run(async (c) => { try { Debug.WriteLine($"{v} started"); await Task.Delay(3000, c); Debug.WriteLine($"{v} completed"); } catch (OperationCanceledException) { Debug.WriteLine($"{v} cancelled"); } }); } }
内容的提问来源于stack exchange,提问作者wforl
相关产品推荐
相关产品推荐

