none
TreeNode.Nodes.Clear阻塞的问题 RRS feed

  • 问题

  • 遇到一奇怪问题,请大牛们请教。现象描述如下:
    我用一个TreeNode(名为TreeRoot)作为根将一些节点组织为一棵树。这些子节点按需部分地显示在一个TreeView中。
    有时需要重新初始化节点树(方法为InitTree)。
    有时需要从其它线程触发重新初始化节点树的操作。
    当我直接从界面线程调用InitTree时,程序正常。
    当我使用Invoke调用InitTree时,对TreeView.Nodes.Clear()的调用没有问题,但对TreeRoot.Nodes.Clear()的调用将导致程序阻塞。
    请大牛帮忙分析一下原因。

    public
     void
     OnPowerSupplyModelRefreshedByOther(object
     sender, EventArgs e)
            {
                if
     (this
    .InvokeRequired)
                {
                    this
    .Invoke(new
     EventHandler(OnPowerSupplyModelRefreshedByOther), new
     object
    [] { sender, e });
                }
                else
    
                {
                    MessageBox.Show("提示"
    );
    
                    PowerSupplyAnalysisControl.RequireData();
    
                    this
    .InitTree();
                }
            } 
    
            ///
     <summary>
    
            ///
     初始化树
    
            ///
     </summary>
    
            ///
     <returns>
    </returns>
    
            public
     int
     InitTree()
            {
    
                TreeRoot.Nodes.Clear();
    
                treeViewPSA.BeginUpdate();
    
                treeViewPSA.Nodes.Clear();            
    
                treeViewPSA.EndUpdate();
    
                return
     1;
            }
    
    2010年2月3日 9:35

答案

  • 你好!
         使用BeginInvoke方法和EndInvoke方法就可以实现异步调用了!
    周雪峰
    • 已标记为答案 泉子 2010年2月4日 7:24
    2010年2月3日 10:54
    版主
  • 你加入 Application.DoEvents();试试
    努力+方法=成功
    • 已标记为答案 泉子 2010年2月4日 7:24
    2010年2月3日 11:01
  • 你好!

    InitTree 也通过 BeginInvoke 或 Invoke 调用。

    知识改变命运,奋斗成就人生!
    • 已标记为答案 泉子 2010年2月4日 7:24
    2010年2月4日 1:07
    版主
  • 你好!
        你把这两行去掉试试 :
              treeViewPSA.BeginUpdate();
              treeViewPSA.EndUpdate();

    周雪峰
    • 已标记为答案 泉子 2010年2月4日 7:24
    2010年2月4日 2:01
    版主
  • 你现在是什么情况,直接界面没有响应,还是等一段时间可以恢复正常,还是抛出异常?
    周雪峰
    • 已标记为答案 泉子 2010年2月4日 7:24
    2010年2月4日 7:07
    版主
  • 你把
    treeViewPSA.BeginUpdate();
    treeViewPSA.EndUpdate();
    彻底删除看看!这种方式有可能阻塞!
    如果还是不行,你可以写一个最简单的能说明这个问题的Sample,然后Email给我:
    xuefeng1982@live.cn
    周雪峰
    • 已标记为答案 泉子 2010年2月4日 7:24
    2010年2月4日 7:18
    版主

全部回复

  • 不好意思,发错版块了,麻烦版主移至.NET一般性问题讨论区
    2010年2月3日 9:50
  • 遇到一奇怪问题,请大牛们请教。现象描述如下:
    我用一个TreeNode(名为TreeRoot)作为根将一些节点组织为一棵树。这些子节点按需部分地显示在一个TreeView中。
    有时需要重新初始化节点树(方法为InitTree)。
    有时需要从其它线程触发重新初始化节点树的操作。
    当我直接从界面线程调用InitTree时,程序正常。
    当我使用Invoke调用InitTree时,对TreeView.Nodes.Clear()的调用没有问题,但对TreeRoot.Nodes.Clear()的调用将导致程序阻塞。
    请大牛帮忙分析一下原因。

    public void OnPowerSupplyModelRefreshedByOther(object sender, EventArgs e)
            {
                if (this.InvokeRequired)
                {
                    this.Invoke(new EventHandler(OnPowerSupplyModelRefreshedByOther), new object[] { sender, e });
                }
                else
                {
                    MessageBox.Show("提示");
    
                    PowerSupplyAnalysisControl.RequireData();
    
                    this.InitTree();
                }
            }
    
     public int InitTree()
            {
                treeViewPSA.BeginUpdate();
    
                treeViewPSA.Nodes.Clear();
    
                TreeRoot.Nodes.Clear();
    
                treeViewPSA.EndUpdate();
    
                return 1;
            }
    2010年2月3日 10:09
  • 你好!
         使用BeginInvoke方法和EndInvoke方法就可以实现异步调用了!
    周雪峰
    • 已标记为答案 泉子 2010年2月4日 7:24
    2010年2月3日 10:54
    版主
  • 你加入 Application.DoEvents();试试
    努力+方法=成功
    • 已标记为答案 泉子 2010年2月4日 7:24
    2010年2月3日 11:01
  • 你好!

    InitTree 也通过 BeginInvoke 或 Invoke 调用。

    知识改变命运,奋斗成就人生!
    • 已标记为答案 泉子 2010年2月4日 7:24
    2010年2月4日 1:07
    版主
  • 我所说阻塞是指
    TreeRoot.Nodes.Clear();
    始终不能执行完成,使程序处于挂起状态。
    2010年2月4日 1:07
  • 请问加在哪?
    2010年2月4日 1:08
  • 你好!
        你把这两行去掉试试 :
              treeViewPSA.BeginUpdate();
              treeViewPSA.EndUpdate();

    周雪峰
    • 已标记为答案 泉子 2010年2月4日 7:24
    2010年2月4日 2:01
    版主
  • 我之前是把
    TreeRoot.Nodes.Clear();
    放在BeginUpdate,EndUpdate外面的.也是不行.
    2010年2月4日 5:32
  • 你现在是什么情况,直接界面没有响应,还是等一段时间可以恢复正常,还是抛出异常?
    周雪峰
    • 已标记为答案 泉子 2010年2月4日 7:24
    2010年2月4日 7:07
    版主
  • 没有响应,始终挂起。
    2010年2月4日 7:09
  • 你把
    treeViewPSA.BeginUpdate();
    treeViewPSA.EndUpdate();
    彻底删除看看!这种方式有可能阻塞!
    如果还是不行,你可以写一个最简单的能说明这个问题的Sample,然后Email给我:
    xuefeng1982@live.cn
    周雪峰
    • 已标记为答案 泉子 2010年2月4日 7:24
    2010年2月4日 7:18
    版主
  • 好的,我暂时改用List来保存节点了。有空再针对这个问题具体测试一下,谢谢!
    2010年2月4日 7:24