在我们的项目中,我们决定在CancellationToken的帮助下为用户提供一个取消机制。
由于工程的结构,我需要一个分层的取消机制。通过层次结构,我的意思是父源取消会导致所有子源被递归取消,但是子源取消不会传播到父源。
在.NET中是否有这种现成的选项?如果没有,我不确定向父令牌注册委托是否足够,或者应该进一步考虑。
发布于 2021-10-11 07:22:53
基于源代码 for Linked2CancellationTokenSource的实现,我介绍了这个实现:
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);
}
}还有一个演示:
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.
*/发布于 2021-10-10 15:21:34
是的,这个功能是现成的。查看CancellationTokenSource.CreateLinkedTokenSource方法。
创建一个
CancellationTokenSource,当任何源令牌处于已取消状态时,该状态将处于已取消状态。
示例:
using var parentCts = new CancellationTokenSource();
using var childrenCts = CancellationTokenSource
.CreateLinkedTokenSource(parentCts.Token);
parentCts.Cancel(); // Cancel the children too
childrenCts.Cancel(); // Doesn't affect the parenthttps://stackoverflow.com/questions/69516354
复制相似问题