首页新闻找找看学习计划

node.text="XXXX" 执行时间过长,winform界面假死

0
悬赏园豆:80 [已解决问题] 解决于 2014-04-15 14:31

如题,用户控件中有一个树,窗体使用了这个控件,但是重命名时执行node.text="XXXX" 执行了很长时间,大约3s,在此期间winform界面夹死,尝试过多线程异步委托的方式来操作, 还是假死

树的数据量比较大,大约1w个节点,避免主界面假死。如何操作呢,可能的原因是什么呢?

问题补充:

补充一点:1w个节点,我只修改了一个节点的名称,就有上述问题

harrell的主页 harrell | 初学一级 | 园豆:14
提问于:2014-04-14 13:35
< >
分享
最佳答案
0

禁止重绘 -> 修改 1 万个节点的 Text 值 -> 恢复重绘。

收获园豆:80
Launcher | 高人七级 |园豆:45045 | 2014-04-14 13:54

1w个节点,我只修改了一个节点的名称

harrell | 园豆:14 (初学一级) | 2014-04-14 14:58

@harrell: 请你在代码中测量下时间,比如类似这样:

t1 = 当前时间; 

node.text="XXXX";

t2 = 当前时间;

你看下 t2 - t1 是多少。

Launcher | 园豆:45045 (高人七级) | 2014-04-14 15:29

@Launcher: 以下代码打印出的时间是00:00:08.7865429

TreeNode node = FindTreeNode(Name);
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
node.Text = (string)sender;
stopwatch.Stop();
Console.WriteLine("Time elapsed: {0}", stopwatch.Elapsed);

harrell | 园豆:14 (初学一级) | 2014-04-14 15:49

@harrell: 检查一下,你针对树控件的节点修改事件绑定了什么操作。

Launcher | 园豆:45045 (高人七级) | 2014-04-14 15:54

@Launcher: 恩,感谢大神,有绑定,但是绑定的几个事件瞬间就执行完了, 软件的逻辑复杂且混乱,都是老代码了,由于代码不公开,没有办法贴出来,这一点很抱歉,感谢各位的帮助,我再好好理一下逻辑,有线索我再反馈

harrell | 园豆:14 (初学一级) | 2014-04-14 17:51

@Launcher: 用Dot trace跟踪了一下还是设置值的时候耗时, 调用堆栈如下

-9,309ms    System.Windows.Forms.TreeNode.set_Text(String)

--9,309ms    System.Windows.Forms.TreeNode.UpdateNode(Int32)

---9,309ms    System.Windows.Forms.TreeView.ForceScrollbarUpdate(Boolean)

----9,309ms    System.Windows.Forms.Control.SendMessage(Int32, Int32, Int32)

-----[Native code]()

------System.Windows.Forms.NativeWindow.Callback(IntPtr, Int32, IntPtr, IntPtr)

-------System.Windows.Forms.Control+ControlNativeWindow.WndProc(Message&)

--------System.Windows.Forms.Control+ControlNativeWindow.OnMessage(Message&)

---------System.Windows.Forms.TreeView.WndProc(Message&)

……以下省略

harrell | 园豆:14 (初学一级) | 2014-04-15 10:30

@harrell: 主要时间花在这里:System.Windows.Forms.TreeView.ForceScrollbarUpdate(Boolean),如果你能给出  System.Windows.Forms.Control.SendMessage(Int32, Int32, Int32) 中前两个参数的值的话就更好了。我猜测这里的值应该是:  System.Windows.Forms.Control.SendMessage(11[WM_SETREDRAW],1,0)。

那么我建议你减少你的树控件上的节点到 100 个左右,然后测试修改节点文本的时间是否显著减少。如果是的话,我们再分析下你的程序的需求,然后我们讨论是否通过自绘制,以及如何自绘树控件来优化显示。

 

另外,你设置未显示节点和显式节点的文本时,是否同样的问题。

Launcher | 园豆:45045 (高人七级) | 2014-04-15 11:04

@Launcher: 原来的节点应该是有几万的,100个节点只要97ms,不到1/10s,请教如何优化显示呢

harrell | 园豆:14 (初学一级) | 2014-04-15 13:41

@harrell: 设置界面上看不见的节点的文本同设置界面上可见的字节的文本,在时间消耗上有不同吗?

Launcher | 园豆:45045 (高人七级) | 2014-04-15 13:44

@Launcher: 时间没有区别,怕是要实现按需加载节点了,如果我还是想加载所有的节点有其他的解决方案吗?

harrell | 园豆:14 (初学一级) | 2014-04-15 14:00

@harrell: 你先用 Double-Buffer 测试下:

SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true);
UpdateStyles();

 

如果没有效果的话,你需要自己绘制。

Launcher | 园豆:45045 (高人七级) | 2014-04-15 14:08

@Launcher: 没有效果,如何自己绘制呢?工程量是不是较大?

harrell | 园豆:14 (初学一级) | 2014-04-15 14:24

@harrell: http://www.codeproject.com/KB/tree/#Custom+Tree+Controls

自己学习吧!大不大根据个人经验而定。

Launcher | 园豆:45045 (高人七级) | 2014-04-15 14:27

@Launcher: 感谢大神的分析和支持,问题找到了,相信解决也就是时间问题了

harrell | 园豆:14 (初学一级) | 2014-04-15 14:30
其他回答(4)
0

费时间的操作由新建的一个线程完成,完成后在操作控件

【秦时明月】 | 园豆:803 (小虾三级) | 2014-04-14 13:42

用一个线程操作了,但是还是卡了3s

支持(0) 反对(0) harrell | 园豆:14 (初学一级) | 2014-04-14 14:57

@harrell: 你自己的问题

支持(0) 反对(0) 【秦时明月】 | 园豆:803 (小虾三级) | 2014-04-14 15:31

@Moon.Orm塑造Orm经典: 我了解是我自己的问题,但是问题出在哪儿还是要研究下

支持(0) 反对(0) harrell | 园豆:14 (初学一级) | 2014-04-14 15:42
0

...重新用一个线程不应该还会卡死的啊,

确定在新线程中操作用户控件了?

seaconch | 园豆:4823 (老鸟四级) | 2014-04-14 15:04

是的,只是一个简单的节点重命名,难道数据太多了重命名很慢? 几万节点不算多吧

支持(0) 反对(0) harrell | 园豆:14 (初学一级) | 2014-04-14 15:08

@harrell: 

Launcher  我觉得你可以用用大神的方法,我觉得可行。

看你的回答,应该是没有试过吧。

支持(0) 反对(0) seaconch | 园豆:4823 (老鸟四级) | 2014-04-14 15:12
0

可以弄一个界面,前端友好显示,后端处理数据

Aiolos丶M | 园豆:149 (初学一级) | 2014-04-14 15:45
0

多线程也卡死?我觉得是不是你的多线程有问题?

Rookier | 园豆:652 (小虾三级) | 2014-04-14 17:00
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册