取消其中一个同时执行的方法

时间:2013-12-06 17:15:37

标签: c# asynchronous c#-5.0 cancellationtokensource

我正在使用Task.WaitAny同时调用3种不同的方法(TrySolution1,TrySolution2和TrySolution3)。我的要求是找到首先执行哪个方法并中止/取消其他方法执行,如果第一个方法返回结果。

尝试使用CancellationTokenSource在第一个方法执行后执行其他任务的取消,但可以看到其他方法仍然执行。

我的代码段:

Task<Boolean>[] tasks = new Task<Boolean>[3];

CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken ct = cts.Token;

tasks[0] = Task<Boolean>.Factory.StartNew(() => TrySolution1());
tasks[1] = Task<Boolean>.Factory.StartNew(() => TrySolution2());
tasks[2] = Task<Boolean>.Factory.StartNew(() => TrySolution3());

Task.WaitAny(tasks, ct);
cts.Cancel();

2 个答案:

答案 0 :(得分:0)

您需要在每次尝试结束时将取消令牌设置为取消,然后在每种方法中检查它以查看它是否在某个时刻被取消。这样的事情......看看Task Cancellation

但要小心。这将设置取消任务,因此尽管一个任务将完成,但仍将设置令牌。

    var tokenSource = new CancellationTokenSource();
    CancellationToken ct = tokenSource.Token;

    var task[0] = Task.Factory.StartNew(() =>
    {

        // Were we already canceled?
        ct.ThrowIfCancellationRequested();

        bool moreToDo = true;
        while (moreToDo)
        {
            // Poll on this property if you have to do 
            // other cleanup before throwing. 
            if (ct.IsCancellationRequested)
            {
                // Clean up here, then...
                ct.ThrowIfCancellationRequested();
            }

        }

        tokenSource.Cancel();
    }, tokenSource.Token); // Pass same token to StartNew.

答案 1 :(得分:0)

没有强制中止已经在TPL中执行的代码。您需要做的是将CancellationToken传递给所有TrySolutionN方法,然后在执行它们时在适当的位置进行检查,或将其传递给您从中调用的方法。

要检查TrySolutionN中是否取消了传入的令牌,请使用ThrowIfCancellationRequested()IsCancellationRequested