[英]Make IEnumerable method async
我有以下节点:
class Node
{
public string Name;
public IEnumerable<Node> Children;
}
我有以下扩展方法:
public static class ExtensionMethods
{
public static IEnumerable<Node> TraverseTree(this Node root)
{
if (root.Children != null)
{
foreach (var child in root.Children)
{
var nodes = TraverseTree(child);
foreach (var node in nodes)
{
yield return node;
}
}
}
yield return root;
}
}
我想在树中搜索名称为“ Foo”的节点。 为此,我这样做:
Node myNode = /* some large tree! */
var search = myNode.TraverseTree().Where(x=>x.Name == "Foo").FirstOrDefault();
我有3个目标
TraverseTree
方法使用yield(IEnumerable)遍历树,以便如果第3个节点的名称为==“ Foo”,则不必遍历整个树。 现在这种情况是真的 。 TraverseTree
方法在单独的线程上运行,因为它可能需要很长时间才能找到。 因此,我猜TraverseTree
方法应该采用callBack参数? 正确的做法是什么?
对不起,我忘了提及我正在使用.Net Framework 4.0
CancellationToken
当然可以添加。 另一个选择是让正在等待遍历的所有内容停止等待,而不是尝试实际停止计算的发生。 首先,我将像这样实现您的功能(注意使用CancellationToken
)
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();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.