C# 取消除最后一个任务以外的所有任务
如何取消除最后/最新任务以外的所有任务?例如,假设我有一个耗时的任务,它是通过单击按钮触发的。我只希望上一个按钮单击后的任务运行,上一个按钮单击后的任务取消。你能告诉我这通常是怎么做的吗 我的尝试包括将所有任务及其取消令牌存储在一个列表中,并在任务完成或取消时删除它们。创建一个列表来存储Task和CancellationToken似乎是我做了太多的事情,因为我认为这是一个常见的要求(例如,用户搜索某个东西并多次单击搜索按钮。不应该只进行最后一次搜索而取消所有其他搜索吗?)。这是一个常见的场景,所以我想知道这通常是如何完成的。这里的最佳实践是什么C# 取消除最后一个任务以外的所有任务,c#,C#,如何取消除最后/最新任务以外的所有任务?例如,假设我有一个耗时的任务,它是通过单击按钮触发的。我只希望上一个按钮单击后的任务运行,上一个按钮单击后的任务取消。你能告诉我这通常是怎么做的吗 我的尝试包括将所有任务及其取消令牌存储在一个列表中,并在任务完成或取消时删除它们。创建一个列表来存储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);
}
}
async void dostufasync()
{
//将任务存储在列表中
if(tasksAndCancelTokens==null)
tasksAndCancelTokens=新列表();
else//我们有一个新的Get请求,因此取消以前的任何请求
tasksAndCancelTokens.ForEach(t=>t.Item2.Cancel());
//创建取消令牌
var cts=新的CancellationTokenSource();
//方法异步运行
Func taskAction=()=>
{
//费时的事
睡眠(5000);
如果(cts.Token.IsCancellationRequested)
cts.Token.ThrowIfCancellationRequested();
返回100;
};
//创建任务
Task Task=Task.Factory.StartNew(taskAction,cts.Token);
//创建元组以在列表中存储任务
var tup=新的Tuple(任务,cts);
tasksAndCancelTokens.Add(tup);
尝试
{
int i=等待任务;
}
捕获(操作取消异常)
{
//不需要做任何事情
}
最后
{
tasksAndCancelTokens.Remove(tup);
}
}
谢谢如果您只想取消上一项任务,那么您只需执行以下操作:
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;
}
}
CancellationTokenSource cts=null;
异步无效按钮1\u单击(…)
{
//取消上一个任务(如果有)。
如果(cts!=null)
cts.Cancel();
//为此任务创建取消令牌。
cts=新的CancellationTokenSource();
var-token=cts.token;
//方法异步运行
Func taskAction=()=>
{
//费时的事
睡眠(5000);
token.ThrowIfCancellationRequested();
返回100;
};
尝试
{
int i=等待任务.Run(taskAction);
}
捕获(操作取消异常)
{
//不需要做任何事情
返回;
}
}
@MitchWheat好的,现在呢?如果你读到我之前的评论,请原谅。因此,如果我在调用cancel后立即忘记了对上一个任务的引用(即,上一个任务可能还没有取消),这并不重要?我越想它,就越有意义,我不需要对上一个cts的引用,因为任务仍然知道它。