取消所有但最后的任务

时间:2013-01-24 05:27:29

标签: 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);
    }
}

由于

1 个答案:

答案 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;
  }
}