1

我正在使用 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();
4

2 回答 2

0

您需要在每次尝试结束时将取消标记设置为取消,然后在每种方法中检查它是否在某个时候被取消。像这样...查看任务取消

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

    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.
于 2013-12-06T17:27:24.103 回答
0

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

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

于 2013-12-06T17:46:53.517 回答