C# 使IEnumerable方法异步
我有以下节点:C# 使IEnumerable方法异步,c#,multithreading,callback,cancellation,C#,Multithreading,Callback,Cancellation,我有以下节点: class Node { public string Name; public IEnumerable<Node> Children; } 我有3个目标 让方法TraverseTree使用yield(IEnumerable)遍历树,这样,如果第三个节点的名称为==“Foo”,那么我就不必遍历整个树。现在这个案子是真的 使方法TraverseTree在单独的线程上运行,因为它可能需要很长时间才能找到。因此我想TraverseTree方法
class Node
{
public string Name;
public IEnumerable<Node> Children;
}
我有3个目标
TraverseTree
使用yield(IEnumerable)遍历树,这样,如果第三个节点的名称为==“Foo”,那么我就不必遍历整个树。现在这个案子是真的李>
TraverseTree
在单独的线程上运行,因为它可能需要很长时间才能找到。因此我想TraverseTree
方法应该采用回调参数CancellationToken
,它由遍历算法、您的子选择器或两者都检查。另一种选择是让等待遍历结果的任何东西停止等待,而不是试图实际停止计算首先,我将这样实现您的函数(注意
CancellationToken
)
之后,如果您想取消,只需拨打:
cts.Cancel();
这个答案有用吗?我不知道是谁投了反对票,但很高兴知道为什么。我很快就会试试的。
Node myNode = /* some large tree! */
var search = myNode.TraverseTree().Where(x=>x.Name == "Foo").FirstOrDefault();
public static IEnumerable<Node> TraverseTree(this Node root, CancellationToken token)
{
if (root.Children != null)
{
foreach (var child in root.Children)
{
if (token.IsCancellationRequested) return; //cancel if requested.
var nodes = TraverseTree(child);
foreach (var node in nodes)
{
yield return node;
if (token.IsCancellationRequested) return; //cancel if requested.
}
}
}
yield return root;
}
var cts = new CancellationTokenSource();
var task = Task.Run(
() => myNode.TraverseTree(cts.Token).Where(x=>x.Name == "Foo").FirstOrDefault(),
cts.Token);
cts.Cancel();