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
    方法应该采用回调参数
  • 最后,它将是很高兴能够取消该操作。我是否也需要向该方法传递取消令牌
  • 正确的做法是什么

    抱歉,我忘了提到我正在使用.Net Framework 4.0

  • 这已经用您拥有的代码完成了。是的,延期执行
  • 到目前为止,更简单的方法是保持方法同步,并将整个查询移动到另一个线程中
  • 是的,您当然可以添加一个
    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();