如何取消除最后/最新任务以外的所有任务?例如,假设我在点击按钮时触发了一个耗时的任务。我只希望从最后一个按钮点击运行的任务和前一个按钮取消。你能告诉我这是怎么做到的吗?
我的尝试涉及将所有任务与其取消令牌一起存储在列表中,并在任务完成或取消时将其删除。创建一个存储Task和CancellationToken的列表似乎我做的太多了,我认为这是一个常见的要求(例如,用户搜索某些内容并多次点击搜索按钮。不仅应该这样做。最后一次搜索和其他所有取消?)。这是一种常见的情况,所以我想知道这是如何做到的。这里的最佳做法是什么?
async void DoStuffAsync()
{
// Store tasks in a list
if (tasksAndCancelTokens == null)
tasksAndCancelTokens = new List<Tuple<Task, CancellationTokenSource>>();
else // we have a new Get request so cancel any previous
tasksAndCancelTokens.ForEach(t => t.Item2.Cancel());
// Create Cancellation Token
var cts = new CancellationTokenSource();
// Method to run asynchonously
Func<int> taskAction = () =>
{
// Something time consuming
Thread.Sleep(5000);
if (cts.Token.IsCancellationRequested)
cts.Token.ThrowIfCancellationRequested();
return 100;
};
// Create Task
Task<int> task = Task<int>.Factory.StartNew(taskAction, cts.Token);
// Create Tuple to store task in list
var tup = new Tuple<Task, CancellationTokenSource>(task, cts);
tasksAndCancelTokens.Add(tup);
try
{
int i = await task;
}
catch (OperationCanceledException)
{
// Don't need to do anything
}
finally
{
tasksAndCancelTokens.Remove(tup);
}
}
由于
答案 0 :(得分:2)
如果您只想取消上一个任务,那么您只需要做的就是:
CancellationTokenSource cts = null;
async void Button1_Click(...)
{
// Cancel the last task, if any.
if (cts != null)
cts.Cancel();
// Create Cancellation Token for this task.
cts = new CancellationTokenSource();
var token = cts.Token;
// Method to run asynchonously
Func<int> taskAction = () =>
{
// Something time consuming
Thread.Sleep(5000);
token.ThrowIfCancellationRequested();
return 100;
};
try
{
int i = await Task.Run(taskAction);
}
catch (OperationCanceledException)
{
// Don't need to do anything
return;
}
}