代码在迭代86处崩溃

时间:2011-02-24 10:34:23

标签: axapta x++

static void Job47(Args _args)
 {
 str                                  path,stx;
 TreeNodeIterator                     iter;
 TreeNode                             treeNode, treeNodeToRelease;
 Map                                  dictMenuDisplay;
 FormName                             formName;
 MenuItemName                         menuItemName;
 container                            conMenu;
 int                                  i,n;
   ;

 for (n=1;n<=100;n++)
       {
        info(strfmt("iter:%1",n));
        path            ="Menu Items\\Display";
        dictMenuDisplay = new Map(Types::String,Types::Container);
        treenode        = Treenode::findNode(path);
        iter            = treenode.AOTiterator();
        treenode        = iter.next();

        while (treenode)
          {
          formName     = treenode.AOTgetProperty("Object");
          menuItemName = treenode.AOTname();

           if (dictMenuDisplay.exists(formName))
            {
             conMenu = dictMenuDisplay.lookup(formName);
             conMenu = conIns(conMenu,conlen(conMenu)+1,menuItemName);
             dictMenuDisplay.insert(formName,conMenu);
             }

           else
             dictMenuDisplay.insert(formName,[menuItemName]);
                      //  treenode = iter.next();

           if(treeNodeToRelease && SysTreeNode::isApplObject(treeNode))
            {
             treeNodeToRelease.treeNodeRelease();
             treeNodeToRelease=null;
            }

           if(SysTreeNode::isApplObject(treeNode))
            {
              treeNodeToRelease=treeNode;
            }

            treeNode=iter.next();
        }
    }
  }

我收到错误“内部运行堆栈溢出”,代码正常运行到第86次迭代,帮助......

3 个答案:

答案 0 :(得分:3)

内核不会立即垃圾收集TreeNode对象。完成应用程序对象及其所有子项的treenode后,需要调用TreeNode.treeNodeRelease(),然后调用treeNode=null;以清理垃圾收集器。

...
TreeNode treeNodeToRelease;
...

while(treenode)
{

    ... /* do stuff with treenode */

    if(treeNodeToRelease && SysTreeNode::isApplObject(treeNode))
    {
        treeNodeToRelease.treeNodeRelease();
        treeNodeToRelease=null;
    }
    if(SysTreeNode::isApplObject(treeNode))
    {
        treeNodeToRelease=treeNode;
    }
    treeNode=iter.next();
}

答案 1 :(得分:0)

代码:

 if(treeNodeToRelease && SysTreeNode::isApplObject(treeNode))

应替换为:

 if (treeNodeToRelease)

对象的释放不应取决于下一个对象。

或者这可能就足够了(取代杰伊的解决方案):

while (treenode)
{
    ... /* do stuff with treenode */
    treeNode.treeNodeRelease();
    treeNode = iter.next();
}

答案 2 :(得分:0)

手册中的引用:

  

如果在同一执行中的许多树节点上运行此方法( treeNodeRelease()),则可能对资源要求很高。你应该在去的时候卸载树节点,让垃圾收集器有机会删除它们。

     

在调用此方法之前,请确保删除对树节点及其子节点的所有引用。

你还有至少85个treeNodeToRelease(和treeNode!)的引用 - &gt;在外部循环结束时调用 treeNodeToRelease.treeNodeRelease()