我有一个看起来像这样的任务:
var task = Task.Factory.StartNew <object>(LongMethod);
task.ContinueWith(TaskCallback, TaskScheduler.FromCurrentSynchronizationContext());
LongMethod 调用一个长时间运行的服务,在此期间我不能(或者至少,我认为我不能)不断地轮询取消令牌以查看它是否已被取消。但是,我对“取消”或忽略回调方法感兴趣。
当 TaskCallback 被调用时,我只对来自最近任务的“结果”感兴趣(让我们假设 LongMethod 调用的服务保留了顺序,并假设用户可以多次单击按钮,但只有最新的一个是相关的)。
我通过以下方式修改了我的代码:创建任务后,我将其添加到堆栈的顶部。在TaskCallback 中,我检查已传递给回调的任务是否是最新的(即堆栈顶部的TryPeek)。如果不是,我只是忽略结果。
private ConcurrentStack<Task> _stack = new ConcurrentStack<Task>();
private void OnClick(object sender, ItemClickEventArgs e)
{
var task = Task.Factory.StartNew < object >( LongMethod);
task.ContinueWith(TaskCallback, TaskScheduler.FromCurrentSynchronizationContext());
_stack.Push(task);
}
private void TaskCallback(Task<object> task)
{
Task topOfStack;
if(_stack.TryPeek(out topOfStack)) //not the most recent
{
if (task != topOfStack) return;
}
//else update UI
}
我很确定这不是“最佳实践”解决方案。但究竟是什么?传递和维护取消令牌似乎也不是那么优雅。