Asynchronous Recursion And Headaches Ohh My!

Asynchronous Recursion And Headaches Ohh My!

Old forum URL: forums.lhotka.net/forums/t/8078.aspx


wjcomeaux posted on Wednesday, December 02, 2009

Well, we've got ourselves into a bit of a pickle. We have written a set of business objects that represent a generic hierarchy. The hierarchyNodes implement an interface that requires a CloneNode ability.

Now, in the Silverlight world we find ourselves needing this method to be asynchronous and that is proving quite difficult to implement.

Basically we would have a root node with n children each of which can also have n children and so on.

Calling myNode.CloneAsync should then do what is necessary to clone everything below it. However, I haven't figured out the proper syntax for what I need so far.

Here is my current code if anyone would like to lend a helping brain. I know the code below doesn't work, it's a work in progress. What I'm wondering is if this is even the correct approach to the problem at hand. Has anyone crossed this bridge? And if so, what car did you drive?

Thanks,
Will (code below)

void IHierarchyNode<T>.CloneNodeAsync(bool iteratively, EventHandler<HierarchyResult<T>> handler)
{
      //Clone this node
      CloneNodeAsync((o, e) =>
      {
         
if (iteratively)
         {
            CloneNodeChildrenAsync(e.Object.HierarchyNodeID, (o1, e1) =>
            {
            });
         
}
      });
}

private void CloneNodeAsync(EventHandler<HierarchyResult<HierarchyNode<T>>> handler)
{
   HierarchyNode<T> clonedHierarchyNode;
   HierarchyNode<T>.NewHierarchyNode((o, e) =>
   {
      clonedHierarchyNode = e.Object;
      clonedHierarchyNode.BeginDateUTC = BeginDateUTC;
      clonedHierarchyNode.EndDateUTC = EndDateUTC;
      clonedHierarchyNode.ParentHierarchyNodeID = ParentHierarchyNodeID;
      handler.Invoke(
this, new HierarchyResult<HierarchyNode<T>>(clonedHierarchyNode, null));
   });
}

private
void CloneNodeAsync(int parentHierarchyNodeID, bool iteratively, EventHandler<HierarchyResult<T>> handler)
{
   //Clone this node but make it's parentNodeID the value passed to the function.
   HierarchyNode<T> clonedHierarchyNode;
   CloneNodeAsync((o, e) =>
   {
      clonedHierarchyNode = (
HierarchyNode<T>)e.Object;
      clonedHierarchyNode.ParentHierarchyNodeID = parentHierarchyNodeID;
      if (iteratively)
      {
         CloneNodeChildrenAsync(clonedHierarchyNode.HierarchyNodeID, (o1, e1) =>
         {
         });
      }
   });
}

private void CloneNodeChildrenAsync(int newHierarchyNodeParentID, EventHandler<HierarchyResult<HierarchyNodeList<T>>> handler)
{
   //Clone all children but use the id of the node passed in as the parentID
   System.Collections.Generic.List<HierarchyNode<T>> list = new
   System.Collections.Generic.List<HierarchyNode<T>>();

   HierarchyNodeList<T> childHierarchyNodeList;
   HierarchyNodeList<T>.GetByParentHierarchyNodeID(HierarchyNodeID, (o, e) =>
   {
      childHierarchyNodeList = e.Object;
      if (childHierarchyNodeList.Count > 0)
      {
         for(int i = 0; i < childHierarchyNodeList.Count; i++)
         {
            HierarchyNode<T> hierarchyNodeChild = childHierarchyNodeListIdea [I];
            HierarchyNode<T> clonedHierarchyNodeChild;
            HierarchyNode<T>.NewHierarchyNode((o1, e1) =>
            {
               clonedHierarchyNodeChild = e1.Object;
               clonedHierarchyNodeChild.BeginDateUTC = hierarchyNodeChild.BeginDateUTC;
               clonedHierarchyNodeChild.EndDateUTC = hierarchyNodeChild.EndDateUTC;
               clonedHierarchyNodeChild.ParentHierarchyNodeID = newHierarchyNodeParentID;
               clonedHierarchyNodeChild.BeginSave((o2, e2) =>
               {
                  hierarchyNodeChild.CloneNodeChildrenAsync(clonedHierarchyNodeChild.HierarchyNodeID, (o3, e3) =>
                  {
                  });
               });
            });
         }
      }
      else
      
{
         handler.Invoke(
this, new HierarchyResult<HierarchyNodeList<T>>(e.Object, null));
      }
   });
}

Copyright (c) Marimer LLC