[英]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.