首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何创建分层CancellationTokenSource?

如何创建分层CancellationTokenSource?
EN

Stack Overflow用户
提问于 2021-10-10 15:05:57
回答 2查看 165关注 0票数 7

在我们的项目中,我们决定在CancellationToken的帮助下为用户提供一个取消机制。

由于工程的结构,我需要一个分层的取消机制。通过层次结构,我的意思是父源取消会导致所有子源被递归取消,但是子源取消不会传播到父源。

在.NET中是否有这种现成的选项?如果没有,我不确定向父令牌注册委托是否足够,或者应该进一步考虑。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-10-11 07:22:53

基于源代码 for Linked2CancellationTokenSource的实现,我介绍了这个实现:

代码语言:javascript
复制
public class HierarchicalCancellationTokenSource : CancellationTokenSource
{
    private readonly CancellationTokenRegistration _parentReg;

    public HierarchicalCancellationTokenSource(CancellationToken parentToken)
    {
        this._parentReg = parentToken.Register(
            static s => ((CancellationTokenSource)s).Cancel(false),
            this,
            useSynchronizationContext: false);
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            this._parentReg.Dispose();
        }

        base.Dispose(disposing);
    }
}

还有一个演示:

代码语言:javascript
复制
CancellationTokenSource[] CreateChildSources(CancellationTokenSource parentSource) =>
    Enumerable.Range(0, 2)
        .Select(_ => new HierarchicalCancellationTokenSource(parentSource.Token))
        .ToArray();

var rootSource = new CancellationTokenSource();
var childSources = CreateChildSources(rootSource);
var grandChildSources = childSources.SelectMany(CreateChildSources).ToArray();

var allTokens = new[] { rootSource.Token }
    .Concat(childSources.Select(s => s.Token))
    .Concat(grandChildSources.Select(s => s.Token))
    .ToArray();

for (int i = 0; i < allTokens.Length; i++)
{
    allTokens[i].Register(
        i => Console.WriteLine(
            $"{new string('+', (int)Math.Log2((int)i))}{i} canceled."),
        i + 1);
}

rootSource.Cancel();

/* Output:
1 canceled.
+3 canceled.
++7 canceled.
++6 canceled.
+2 canceled.
++5 canceled.
++4 canceled.
*/
票数 3
EN

Stack Overflow用户

发布于 2021-10-10 15:21:34

是的,这个功能是现成的。查看CancellationTokenSource.CreateLinkedTokenSource方法。

创建一个CancellationTokenSource,当任何源令牌处于已取消状态时,该状态将处于已取消状态。

示例:

代码语言:javascript
复制
using var parentCts = new CancellationTokenSource();
using var childrenCts = CancellationTokenSource
    .CreateLinkedTokenSource(parentCts.Token);

parentCts.Cancel(); // Cancel the children too
childrenCts.Cancel(); // Doesn't affect the parent
票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69516354

复制
相关文章

相似问题

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