0

我有一个函数可以加载节点的子节点。它在内部调用 WCF 异步服务进行加载。签名如下。

public void AddChildElements(Node parentElement, 
                                    Action<IEnumerable<Node>> callback)
{

}

这可以像这样使用

_nodeBuilder.AddChildElements(parentElement, (elements) =>
              {
                 //do something with elements 
              });

现在我想编写一个函数来根据某些条件扩展层次结构。所以我写了一个这样的扩展函数

public static T LoadHierarchyUntilItemFound<T>(
         this  IEnumerable<T> sequence, Func<T, List<T>> loadaction, 
         Func<T, string> searchstring)
{
  //...
}

loadaction 参数期望节点的加载函数。用法如下

 Elements.LoadHierarchyUntilItemFound(LoadChildren,                               
                                   "root.UK.England.London"); 

问题是我将如何编写加载函数?

  private List<Node> LoadChildren(Node parent)
   {
           // _nodeBuilder.AddChildElements(parent, here it expects a callback 
                        //which gives the result, how to use this?); 
   }

简而言之,问题是如何使用回调函数返回包装函数的结果?

4

1 回答 1

1

If you really want it is possible to just make a function that calls the async method and blocks until it returns:

private List<Node> LoadChildren(Node parent)
{
    var tcs = new TaskCompletionSource<IEnumerable<Node>>();

    AddChildElements(parent, nodes => tcs.SetResult(nodes));

    return tcs.Task.Result.ToList();
}

However, in many contexts it would be preferable to do this entire thing asynchronously, rather than synchronously.

public static async Task<T> LoadHierarchyUntilItemFoundAsync<T>(
    this  IEnumerable<T> sequence, Func<T, Task<IEnumerable<T>>> loadaction,
    Func<T, string> selector, string searchstring)
{
    var stack = new Stack<T>(sequence);
    while (stack.Any())
    {
        var item = stack.Pop();

        if (selector(item) == searchstring)
            return item;

        foreach (var child in await loadaction(item))
        {
            stack.Push(child);
        }
    }

    return default(T);
}

Given a function like that you can call it using:

Elements.LoadHierarchyUntilItemFound(AddChildElements,                               
                               "root.UK.England.London"); 
于 2013-02-05T19:15:04.390 回答