首页 > 代码库 > C# 在子线程中创建不会阻塞执行窗体
C# 在子线程中创建不会阻塞执行窗体
可以参考”C# 对 Windows 窗体控件进行线程安全调用“一文来看。
在做网络连接程序的时候碰到一个问题:每当连接到来时,都创建一个新的接收线程,而该接收线程在接收到消息时,可以创建一个新的对话窗口,而该窗口不能阻塞该接收线程的下一轮消息的接收,而且该接收线程还要把接收到的消息显示在该窗口上
Form.ShowDialog();方法弹出模态对话框,而模态对话框会阻塞后面代码的执行,导致接收线程无法继续执行(除非该模态窗口被关闭)
刚开始想到的解决办法,就是:通过Form.Show();方法,显示非模态的窗口
非模态对话框有几个问题:
(1) 生命期限问题:由于是在线程的一轮执行中创建的,所以,该对象可能在该轮结束后被垃圾回收机制自动清除掉;
(2) 模态对话框没有系统消息机制,需要自己写;(好像是这样的,没用过...)
(3) 在代码中尝试了一下,没有创建消息机制,只是显示窗口。但该窗口处于假死状态,根本没法用。
由于上述的几个困难,只能另觅它途了...
成功实验-----异步委托
在看其他文章的时候,偶然看到Control.Invoker()方法,该方法可执行自定义或系统定义的委托。
突然想起来,委托可以通过用Invoke()方法同步执行(阻塞执行),而通过BeginInvoke()方法异步执行,如果是异步执行的话,应该是不会阻塞线程的执行吧...
于是,做了如下的例子:
注意事项:
通过Invoke()/BeginInvoke()调用委托,必须由已经出现的控件来调用,否则会出现错误提示:“未经处理的异常: System.InvalidOperationException: 在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke。”
1) 打开窗口代码:
- void openNewForm()
- {
- Form2 newForm = new Form2();
- newForm.ShowDialog();
- }
(2) 线程入口函数
- //线程入口函数
- void _threadProc()
- {
- //定义一个委托实例,该实例执行打开窗口代码
- MethodInvoker mi = new MethodInvoker(openNewForm);
- BeginInvoke(mi);
- //如果没有阻塞的话,该段代码应该可执行
- Console.WriteLine("新打开的窗口没有阻塞之后的执行");
- Console.ReadLine();
- }
(3) 创建,并执行线程
- Thread newThread = new Thread(new ThreadStart(_threadProc));
- newThread.Start();
4) 设置项目的输出类型为:控制台应用程序(这样执行的时候会同时弹出控制台和窗口)
执行结果如下:
可见,新打开的模式窗口并没有阻塞线程的执行!
因为,如果是同步调用的话,在Form2窗口关闭之前,“新打开的窗口没有阻塞之后的执行”就不会有输出。
本文非自创,可查看原文:http://blog.csdn.net/xiaobai1593/article/details/7290421
C# 在子线程中创建不会阻塞执行窗体