【问题标题】:Cancelling one of the concurrently executed methods取消同时执行的方法之一
【发布时间】:2013-12-06 17:15:37
【问题描述】:

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

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

我的代码sn-p:

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();

【问题讨论】:

    标签: c# asynchronous c#-5.0 cancellationtokensource


    【解决方案1】:

    您需要在每次尝试结束时将取消标记设置为取消,然后在每个方法中检查它是否在某个时间点被取消。像这样的...查看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.
    

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 2021-10-19
        • 2012-11-09
        • 2014-04-20
        • 1970-01-01
        • 2013-09-14
        • 2019-10-04
        • 2014-04-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多