如题,用户控件中有一个树,窗体使用了这个控件,但是重命名时执行node.text="XXXX" 执行了很长时间,大约3s,在此期间winform界面夹死,尝试过多线程异步委托的方式来操作, 还是假死
树的数据量比较大,大约1w个节点,避免主界面假死。如何操作呢,可能的原因是什么呢?
补充一点:1w个节点,我只修改了一个节点的名称,就有上述问题
禁止重绘 -> 修改 1 万个节点的 Text 值 -> 恢复重绘。
1w个节点,我只修改了一个节点的名称
@harrell: 请你在代码中测量下时间,比如类似这样:
t1 = 当前时间;
node.text="XXXX";
t2 = 当前时间;
你看下 t2 - t1 是多少。
@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: 检查一下,你针对树控件的节点修改事件绑定了什么操作。
@Launcher: 恩,感谢大神,有绑定,但是绑定的几个事件瞬间就执行完了, 软件的逻辑复杂且混乱,都是老代码了,由于代码不公开,没有办法贴出来,这一点很抱歉,感谢各位的帮助,我再好好理一下逻辑,有线索我再反馈
@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: 主要时间花在这里: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: 原来的节点应该是有几万的,100个节点只要97ms,不到1/10s,请教如何优化显示呢
@harrell: 设置界面上看不见的节点的文本同设置界面上可见的字节的文本,在时间消耗上有不同吗?
@Launcher: 时间没有区别,怕是要实现按需加载节点了,如果我还是想加载所有的节点有其他的解决方案吗?
@harrell: 你先用 Double-Buffer 测试下:
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true);
UpdateStyles();
如果没有效果的话,你需要自己绘制。
@Launcher: 没有效果,如何自己绘制呢?工程量是不是较大?
@harrell: http://www.codeproject.com/KB/tree/#Custom+Tree+Controls
自己学习吧!大不大根据个人经验而定。
@Launcher: 感谢大神的分析和支持,问题找到了,相信解决也就是时间问题了
费时间的操作由新建的一个线程完成,完成后在操作控件
用一个线程操作了,但是还是卡了3s
@harrell: 你自己的问题
@Moon.Orm塑造Orm经典: 我了解是我自己的问题,但是问题出在哪儿还是要研究下
...重新用一个线程不应该还会卡死的啊,
确定在新线程中操作用户控件了?
是的,只是一个简单的节点重命名,难道数据太多了重命名很慢? 几万节点不算多吧
可以弄一个界面,前端友好显示,后端处理数据
多线程也卡死?我觉得是不是你的多线程有问题?