winform界面如何实现异步加载,WinForm(九)UI加载
由于WinForm的UI是绘制的,所以在加载大量数据数据时会有一定的延时,本篇就讨论几个减少延时的方法。
在加载有规律数据时,可以考虑用递归,简单方便快捷来加载数据,如下,把一个文件夹下的所有文件或文件夹加载到树形菜单上,以树形展示,代码实现如下。
varrootPath = "d://abc/bcd"; varrootNode = treeVie1.Nodes.Add(rootPath, Path.GetFileName(rootPath)); LoadFile(rootNode); voidLoadFile(TreeNode node){ foreach(varfile inDirectory.GetFiles(node.Name)) { node.Nodes.Add(file, Path.GetFileName(file)); } foreach(vardir inDirectory.GetDirectories(node.Name)) { varchildNode = node.Nodes.Add(dir, Path.GetFileName(dir)); LoadFile(childNode); } }
上面的是练了个手,接下来我们加载一个大点的数据,一个全国的行政区划表,有省,市 ,县,乡镇四级,一共49000多条数据,数据字段有sid,pid,name。本篇我们主要是看从内存list到UI上,所以加载数据不是重点,可以是数据库,也可以是文件中,最终数据会在内存的list中。
classProvince{ publicstringsid { get; set; } publicstringpid { get; set; } publicstringname { get; set; } }
varrootNode = treeVie1.Nodes.Add("0", "中国"); LoadProvince(rootNode); voidLoadProvince(TreeNode node){ foreach(varitem inlist.Where(s => s.pid == node.Name)) { varchildNode = node.Nodes.Add(item.sid, item.name); LoadProvince(childNode); } }
如果直接用递归加载,速度太慢,为了加快速度,就得并行加载了,于时就增加Task.Run,因为是大多线程中异步操作UI,所以还得用this.Invoke,代码如下。运行,会看到,速度显然快了不了,但还不是理想结果,理想是无感。
varrootNode = treeVie1.Nodes.Add("0", "中国"); LoadProvince(rootNode); voidLoadProvince(TreeNode node) { Task.Run(()=>{ foreach (varitem inlist.Where(s=>s.pid == node.Name).OrderBy(s=>s.sid)) { this.Invoke(()=>{ node.Nodes.Add(item.sid, item.name); if(node.Level == 0) { node.Expand(); } }); } foreach (TreeNode childNode innode.Nodes) { LoadProvince(childNode); } }); }
后来又想到,可不可以把树形菜单给序列化,窗体启动时,返序列化回来,用BinaryFormatter来实现(现在官方不鼓励用),TreeVie不支持序列化,只能换成TreeVie的Nodes属笥来序列化。窗体启动时,它的加载速度与上面的异步递归差不多,没有明显改善。
即然一次加载大量数据不行,就再换一下思路,一次加载少一些,因为是UI,用户肯定有交互,利用用户的交互来触发加载他想要看的数据,这个少量多少为好,对于树形控件来说,如果想看不出来,那就是两级,用户点开第二级的时候再加载两级,这样用户始终感觉用数据。
privatevoidForm1_Load(objectsender, EventArgs e){ varrootNode = treeVie2.Nodes.Add("0", "中国"); LoadProvince(rootNode, 1); this.treeVie2.BeforeExpand += neSystem.Windos.Forms.TreeVieCancelEventHandler(this.treeVie2_BeforeExpand); } privatevoidtreeVie2_BeforeExpand(objectsender, TreeVieCancelEventArgs e){ if(e.Node != null& e.Node.Nodes != null&&e.Node.Nodes.Count > 0) { e.Node.Nodes.Clear(); LoadProvince(e.Node, 1); } }
性能的问题永远没有最好,也没有一种方式能就通吃各种场景,得一个个换思路来解决,不过上面的思路肯定不是最好的,如果你有一次性加载全部更快的解决方案,请告我,我实现,然后再分享给更多的人。
电脑操作系统
- 电脑系统一键重装 电脑系统一键重装软件排行榜
- win10一键还原和重装系统 win10一键还原和重装系统
- 开机按f12怎么重装系统 电脑按f12怎么重装系统
- 大白菜一键重装系统 大白菜一键重装系统怎么样
- u盘重装win10系统步骤 u盘重装win10步骤知乎
- win7官方纯净版系统 win7纯净版系统哪个最好
- win10系统安装教程 win10系统安装教程u盘怎么制作
- 电脑系统坏了怎么修复 电脑系统坏了怎么修复
- 最干净的一键重装系统 一键重装系统哪个好知乎
- 新手自己用u盘怎么装系统 怎样从u盘安装系统到
- win7怎么升级到win10系统 win7怎么升级到win10系统不
- u盘启动盘怎么装系统 u盘启动盘怎么装系统dell
- 电脑死机 电脑死机重启无法开机
- 电脑数据恢复 电脑数据恢复软件免费版破解版
- 怎么看电脑型号 怎么看电脑型号配置
- 手机怎么连接电脑 手机怎么连接电脑热点共享网