簡體   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