繁体   English   中英

使IEnumerable方法异步

[英]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个目标

  1. 使用TraverseTree方法使用yield(IEnumerable)遍历树,以便如果第3个节点的名称为==“ Foo”,则不必遍历整个树。 现在这种情况是真的
  2. 使TraverseTree方法在单独的线程上运行,因为它可能需要很长时间才能找到。 因此,我猜TraverseTree方法应该采用callBack参数?
  3. 最后,很高兴能够取消该操作。 我是否还需要将取消令牌传递给该方法?

正确的做法是什么?

对不起,我忘了提及我正在使用.Net Framework 4.0

  1. 这已经用您拥有的代码完成了。 是的,推迟执行。
  2. 到目前为止,最简单的方法是使方法保持同步并将整个查询移到另一个线程中。
  3. 是的,可以通过遍历算法,子选择器或两者进行检查的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM