-1

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

我的尝试涉及将所有任务及其取消令牌存储在列表中,并在任务完成或取消时将其删除。创建一个列表来存储 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);
    }
}

谢谢

4

1 回答 1

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;
  }
}
于 2013-01-24T17:06:06.557 回答