Winform界面异步初始化
来源:互联网 发布:linux文件用户权限 编辑:程序博客网 时间:2024/05/10 00:28
问题描述:
WinForm系统在系统跳转过程中出现了长时间的卡顿现象(10s),这样长时间的界面卡顿显然是不被允许,界面跳转控制在1s以内还是可以接受的。
问题分析:
造成这样的卡顿应该是目标页面需要初始化的资源过多造成的,分析了一下目标页面的布局,总共包含四个控件:一个ToolStripContainer,一个AxMapControl,一个ToolBar 和N多个ToolStripButton。
而这些控件都是在可视化布局视图中通过拖拽控件布局的,对应的初始化代码均在InitComponent()中完成,而这个函数是在Load之前,在跳转之前的卡顿肯定是必然的了。
解决办法:
解决这个问题自然想到的就是延迟目标页面控件的初始化,在页面加载完成后再进行内部页面的生成。我首先采用的办法是使用多线程方法,即在Load事件响应中声明一个线程,让该线程负责后续控件的生成,但是该方法会造成下图的问题:当前线程不在单线程单元中无法实例化ActiveX控件(AxMapControl是一个ActiveX控件)。这个是因为COM对象的套间问题(套间是深入浅出COM中提到的翻译),那么将线程模型改为单套间呢?
private void SpatialMainControl_Load(object sender, EventArgs e){ Thread initThread = new Thread(new ThreadStart(InitControl)); initThread.SetApartmentState(ApartmentState.STA); initThread.Start();}
调用 initThread.SetApartmentState(ApartmentState.STA);将当前线程修改为单套间,但是依然没用。程序报异常:在某个线程上创建的空间不能成为在另一个线程上创建的空间的父级。这个异常说明目前Winform不支持跨进程修改UI啊,看起来只能在UI进程中修改了,在主线程中加载界面但是又不能阻塞怎么办?查了资料后发现Winform的Control提供了一个异步方法BeginInvoke,根据博客http://www.fx114.net/qa-246-76092.aspx中的分析,这货其实就是将委托对应的函数地址封装了放到主线程消息队列中,由主线程调用,但是当前调用立刻返回,不会阻塞当前线程,Ok就用这个方法了。
private void SpatialMainControl_Load(object sender, EventArgs e){ BeginInvoke(new Action(InitControl));}果然解决了问题,真是吃一堑,长一智啊。
总结:
1、负载界面布局尽量使用动态布局;
2、使用异步方法加载界面;
欢迎交流:QQ:1936856741 ; E-mail:zhaozhipeng1000@126.com
- Winform界面异步初始化
- Winform异步界面调用设计
- winform异步线程防止界面卡死
- C#中异步及winform中界面假死
- WinForm委托修改界面,异步处理无响应。
- winform 异步
- C# winform: 初始化ListView
- 初始化资源管理器 winform
- Winform异步调用WebService
- Winform异步调用WebService
- winform异步调用
- Winform 界面 美化 界面库
- winform界面美化
- C# 打印winform 界面
- WinForm界面优化工具
- WinForm 界面布局
- 关于winform界面美化。
- winForm欢迎界面
- 南邮 OJ 1010 数的计算
- H.264编码器原理
- jQuery如何获取Json中的某个数据。
- LeetCode OJ 之 Implement Trie (Prefix Tree) 实现Trie(前缀树)
- C#将字节数组加到List中
- Winform界面异步初始化
- H.264解码器原理
- Game! SDUT(环形博弈)
- 杭电 2041 超级楼梯 递归
- 数据库连接错误---------
- eclipse4.2版本下面安装ADT,安装已经完成了,但没有ADT的那个图标显示
- Java代码实现“年-月-日 上午/下午时:分:秒”
- 生活中吃一堑长一智的小事儿(实时更新)
- 怎样才能读透一本书