首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在.NET 6 Parallel.ForEachAsync中需要两个令牌吗?

在.NET 6 Parallel.ForEachAsync中需要两个令牌吗?
EN

Stack Overflow用户
提问于 2021-12-01 21:15:30
回答 2查看 648关注 0票数 3

我正在试验如何打破ForEachAsync循环。break不工作,但我可以在CancellationTokenSource上调用CancelForEachAsync的签名有两个令牌-一个作为独立参数,另一个在Func主体签名中。

我注意到,当调用cts.Cancel()时,tokent变量都将IsCancellationRequested设置为true。所以,我的问题是:这两个独立的token参数的目的是什么?有什么区别值得注意吗?

代码语言:javascript
复制
List<string> symbols = new() { "A", "B", "C" };
var cts = new CancellationTokenSource();
var token = cts.Token;
token.ThrowIfCancellationRequested();

try
{
    await Parallel.ForEachAsync(symbols, token, async (symbol, t) =>
    {
        if (await someConditionAsync())
        {
            cts.Cancel();
        }
    });
catch (OperationCanceledException oce)
{
    Console.WriteLine($"Stopping parallel loop: {oce}");
}
finally
{
    cts.Dispose();
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-12-01 21:47:35

传递给ForEachAsync调用的方法主体的令牌是一个不同的标记,来自将被取消的内部CancellationTokenSource

  • 在“外部”取消 (这就是为什么在调用cts.Cancel()时看到t.IsCancellationRequested设置为true的原因)
  • 出于内部原因(我发现了一个--任何迭代抛出了一个不寻常的异常)。

因此,传递给cancellationToken CancellationTokenParallel.ForEachAsync参数的目的是支持调用方的取消,以及传递给它调用的异步委托的取消--支持外部(即调用方)和内部源(参见P.S.)的取消。

附注:

还请注意,通常传递和检查方法中的令牌状态是个好主意(例如,await someConditionAsync(t)中有相应的实现),因为CancelationToken用于所谓的协同取消

票数 3
EN

Stack Overflow用户

发布于 2021-12-01 21:48:11

Parallel.ForEachAsync接受一个令牌,您可以使用它取消for-each (函数的输入),该令牌也传递给for-each的每一次迭代(向lambda输入)。

将取消令牌传递给lambda的原因之一是避免捕获位于lambda表达式之外的变量。

想象一下这段代码:

代码语言:javascript
复制
await Parallel.ForEachAsync(symbols, token, async (symbol, t) => MyCode(symbol, t));

Task async MyCode(string symbol, CancellationToken token)
{
    if (await someConditionAsync())
    {
        cts.Cancel();
    }
});

以这种方式编写,MyCode没有访问token的权限。

使用lambda意味着可以“继承”lambda之外的变量,但这并不意味着您应该继承。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70191295

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档