2013-01-24 70 views
-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); 
    } 
} 

感谢

+0

@MitchWheat好了,如何回合呢? – Steve

回答

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; 
    } 
} 
+0

对于我以前的评论,如果你阅读了这一点,很抱歉。因此,在我呼叫取消后,如果我忘记了对最后一项任务的引用(即最后一项任务尚未取消),这并不重要? – Steve

+0

我越想越觉得它越有意义,我不需要引用最后一个cts,因为任务仍然知道它。 – Steve

相关问题