C# 取消除最后一个任务以外的所有任务

C# 取消除最后一个任务以外的所有任务,c#,C#,如何取消除最后/最新任务以外的所有任务?例如,假设我有一个耗时的任务,它是通过单击按钮触发的。我只希望上一个按钮单击后的任务运行,上一个按钮单击后的任务取消。你能告诉我这通常是怎么做的吗 我的尝试包括将所有任务及其取消令牌存储在一个列表中,并在任务完成或取消时删除它们。创建一个列表来存储Task和CancellationToken似乎是我做了太多的事情,因为我认为这是一个常见的要求(例如,用户搜索某个东西并多次单击搜索按钮。不应该只进行最后一次搜索而取消所有其他搜索吗?)。这是一个常见的场景,所

如何取消除最后/最新任务以外的所有任务?例如,假设我有一个耗时的任务,它是通过单击按钮触发的。我只希望上一个按钮单击后的任务运行,上一个按钮单击后的任务取消。你能告诉我这通常是怎么做的吗

我的尝试包括将所有任务及其取消令牌存储在一个列表中,并在任务完成或取消时删除它们。创建一个列表来存储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的引用,因为任务仍然知道它。