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# 在子线程中创建不会阻塞执行窗体的更多相关文章
- C# 在窗体的子线程中创建新窗体
在子线程中如果简单的调用新窗体的话,新出来的窗体会直接一闪而过.没有停留.效果很差 具体解决方法 如下: 在母窗体中建立委托 public delegate void setShowChartForm ...
- Windows:子线程中创建窗口
一般来讲,UI的所有操作都必须在主线程,否则会出现未知错误.但有时候我们会需要一个功能比较单一的窗口,同时希望他在一个单独的线程运行.并不影响主线程的效率. 下面说明一下新建子线程创建的新窗口的方法, ...
- MFC在子线程中创建窗口(PostMessage方法)
1.创建子线程 C++创建线程的方式比较多 1)最简单易用的<thread>头文件,但是这种方法创建的子线程中无法给主线程PostMessage消息(也可能是我操作有误,总之没成功) 2) ...
- android 不能在子线程中更新ui的讨论和分析
问题描写叙述 做过android开发基本都遇见过 ViewRootImpl$CalledFromWrongThreadException,上网一查,得到结果基本都是仅仅能在主线程中更改 ui.子线程要 ...
- Android--Handler的用法:在子线程中更新界面
本文主要介绍Android的Handler的用法.Handler能够发送Messsage和Runnable对象到与其相关联的线程的消息队列. 每一个Handler对象与创建它的线程相关联.而且每一个H ...
- 【第三篇】学习 android 事件总线androidEventbus之发布事件,子线程中接收
发送和接收消息的方式类似其他的发送和接收消息的事件总线一样,不同的点或者应该注意的地方: 1,比如在子线程构造方法里面进行实现总线的注册操作: 2,要想子线程中接收消息的功能执行,必须启动线程. 3, ...
- 线程中使用SaveFileDialog不能弹出窗体
在子线程中使用 SaveFileDialog 无法弹出窗体,主要是我们需要用主线程去处理SaveFileDialog , 我们可以将子线程进行如下设置: public partial class Fo ...
- 【转载】Delphi7从子线程中发送消息到主线程触发事件执行
在对数据库的操作时,有时要用一个子线程来进行后台的数据操作.比如说数据备份,转档什么的.在主窗口还能同是进行其它操作.而有时后台每处理一个数据文件,要向主窗口发送消息,让主窗口实时显示处理进度在窗口上 ...
- 在子线程中new Handler报错--Can't create handler inside thread that has not called Looper.prepare()
在子线程中new一个Handler为什么会报以下错误? java.lang.RuntimeException: Can't create handler inside thread that has ...
随机推荐
- 关于MFC库和CRT库冲突的分析
当MFC库和CRT库冲突时,会出现一个LNK2005的错误.具体的错误如下: nafxcwd.lib(dllmodul.obj): error LNK2005: _DllMain@12 already ...
- HTTP权威指南学习心得
一.HTTP请求的步骤: 1.从url中读取主机名 2.利用DNS(domain name service)对主机名进行转换,得到IP地址 3.如果有端口号的话,读取端口号 4.根据IP地址和端口号, ...
- C语言中和指针相关的四道题目
例子1. void fun (int *x , int *y) { printf("%d, %d", *x, *y) ; *x = 3; *y = 4;} main(){ int ...
- Python练习题 027:对10个数字进行排序
[Python练习题 027] 对10个数字进行排序 --------------------------------------------- 这题没什么好说的,用 str.split(' ') 获 ...
- Android进阶笔记17:3种JSON解析工具(org.json、fastjson、gson)
一. 目前解析json有三种工具:org.json(Java常用的解析),fastjson(阿里巴巴工程师开发的),Gson(Google官网出的),其中解析速度最快的是Gson. 3种json工具下 ...
- Jquery 实现点击一个页面跳转后在另外一个页面显示指定位置
<script> $(function(){ var isTarget = '<?php echo $_GET['target']; ?>'; if (isTarget != ...
- VS2008/MVC2 项目迁移到 VS2013/MVC4
第1步.MVC2 => MVC3 手动处理可以参考这个: http://www.asp.net/whitepapers/mvc3-release-notes#upgrading 使用工具 ASP ...
- javascript中Math ceil(),floor(),round()三个函数的对比
Math.ceil()执行的是向上舍入 Math.floor()执行向下舍入 Math.round()执行标准舍入 一下是一些补充: ceil():将小数部分一律向整数部分进位. 如: Math.ce ...
- 剑指Offer39 数组中寻找和为sum的两个数字
/************************************************************************* > File Name: 39_TwoNum ...
- codeforces 675D D. Tree Construction(线段树+BTS)
题目链接: D. Tree Construction D. Tree Construction time limit per test 2 seconds memory limit per test ...