可以参考”C# 对 Windows 窗体控件进行线程安全调用“一文来看。

在做网络连接程序的时候碰到一个问题:每当连接到来时,都创建一个新的接收线程,而该接收线程在接收到消息时,可以创建一个新的对话窗口,而该窗口不能阻塞该接收线程的下一轮消息的接收,而且该接收线程还要把接收到的消息显示在该窗口上

Form.ShowDialog();方法弹出模态对话框,而模态对话框会阻塞后面代码的执行,导致接收线程无法继续执行(除非该模态窗口被关闭)

刚开始想到的解决办法,就是:通过Form.Show();方法,显示非模态的窗口

非模态对话框有几个问题:

(1) 生命期限问题:由于是在线程的一轮执行中创建的,所以,该对象可能在该轮结束后被垃圾回收机制自动清除掉;

(2) 模态对话框没有系统消息机制,需要自己写;(好像是这样的,没用过...)

(3) 在代码中尝试了一下,没有创建消息机制,只是显示窗口。但该窗口处于假死状态,根本没法用。

由于上述的几个困难,只能另觅它途了...

成功实验-----异步委托

在看其他文章的时候,偶然看到Control.Invoker()方法,该方法可执行自定义或系统定义的委托。

突然想起来,委托可以通过用Invoke()方法同步执行(阻塞执行),而通过BeginInvoke()方法异步执行,如果是异步执行的话,应该是不会阻塞线程的执行吧...

于是,做了如下的例子:

注意事项:

通过Invoke()/BeginInvoke()调用委托,必须由已经出现的控件来调用,否则会出现错误提示:“未经处理的异常:  System.InvalidOperationException: 在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke。”

1) 打开窗口代码:

  1. void openNewForm()
  2. {
  3. Form2 newForm = new Form2();
  4. newForm.ShowDialog();
  5. }

(2) 线程入口函数

  1. //线程入口函数
  2. void _threadProc()
  3. {
  4. //定义一个委托实例,该实例执行打开窗口代码
  5. MethodInvoker mi = new MethodInvoker(openNewForm);
  6. BeginInvoke(mi);
  7. //如果没有阻塞的话,该段代码应该可执行
  8. Console.WriteLine("新打开的窗口没有阻塞之后的执行");
  9. Console.ReadLine();
  10. }

(3) 创建,并执行线程

  1. Thread newThread = new Thread(new ThreadStart(_threadProc));
  2. newThread.Start();

4) 设置项目的输出类型为:控制台应用程序(这样执行的时候会同时弹出控制台和窗口)

执行结果如下:

可见,新打开的模式窗口并没有阻塞线程的执行!

因为,如果是同步调用的话,在Form2窗口关闭之前,“新打开的窗口没有阻塞之后的执行”就不会有输出。

本文非自创,可查看原文:http://blog.csdn.net/xiaobai1593/article/details/7290421

C# 在子线程中创建不会阻塞执行窗体的更多相关文章

  1. C# 在窗体的子线程中创建新窗体

    在子线程中如果简单的调用新窗体的话,新出来的窗体会直接一闪而过.没有停留.效果很差 具体解决方法 如下: 在母窗体中建立委托 public delegate void setShowChartForm ...

  2. Windows:子线程中创建窗口

    一般来讲,UI的所有操作都必须在主线程,否则会出现未知错误.但有时候我们会需要一个功能比较单一的窗口,同时希望他在一个单独的线程运行.并不影响主线程的效率. 下面说明一下新建子线程创建的新窗口的方法, ...

  3. MFC在子线程中创建窗口(PostMessage方法)

    1.创建子线程 C++创建线程的方式比较多 1)最简单易用的<thread>头文件,但是这种方法创建的子线程中无法给主线程PostMessage消息(也可能是我操作有误,总之没成功) 2) ...

  4. android 不能在子线程中更新ui的讨论和分析

    问题描写叙述 做过android开发基本都遇见过 ViewRootImpl$CalledFromWrongThreadException,上网一查,得到结果基本都是仅仅能在主线程中更改 ui.子线程要 ...

  5. Android--Handler的用法:在子线程中更新界面

    本文主要介绍Android的Handler的用法.Handler能够发送Messsage和Runnable对象到与其相关联的线程的消息队列. 每一个Handler对象与创建它的线程相关联.而且每一个H ...

  6. 【第三篇】学习 android 事件总线androidEventbus之发布事件,子线程中接收

    发送和接收消息的方式类似其他的发送和接收消息的事件总线一样,不同的点或者应该注意的地方: 1,比如在子线程构造方法里面进行实现总线的注册操作: 2,要想子线程中接收消息的功能执行,必须启动线程. 3, ...

  7. 线程中使用SaveFileDialog不能弹出窗体

    在子线程中使用 SaveFileDialog 无法弹出窗体,主要是我们需要用主线程去处理SaveFileDialog , 我们可以将子线程进行如下设置: public partial class Fo ...

  8. 【转载】Delphi7从子线程中发送消息到主线程触发事件执行

    在对数据库的操作时,有时要用一个子线程来进行后台的数据操作.比如说数据备份,转档什么的.在主窗口还能同是进行其它操作.而有时后台每处理一个数据文件,要向主窗口发送消息,让主窗口实时显示处理进度在窗口上 ...

  9. 在子线程中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 ...

随机推荐

  1. Java获取当前进程的所有线程

    public class MainClass { public static void main(String[] args) { ThreadGroup group = Thread.current ...

  2. jQuery显示和隐藏 常用的状态判断方法

    显示:show()  display:block; 隐藏:hide()   display:none; 当显示和隐藏切换的时候,需要判断此刻是显示还是隐藏,那判断条件常用以下几种方法: 1.if(th ...

  3. 机顶盒Demux

    主页http://www.videolan.org/vlc/ 机顶盒软件开发仿真平台的设计与实现http://max.book118.com/html/2012/0311/1260745.shtm

  4. BeginInvoke、ThreadPool、Task三类异步方法的区别和速度比较

      速度(最快为1) 返回值 多参数 等待在时限内完成 超时后结束 ThreadPool.UnsafeQueueUserWorkItem() 1 非原生支持1 非原生支持 非原生支持3 不支持 Thr ...

  5. django 用imagefiled访问图片

    使用FileField和ImageField时,我们有几个步骤: 在settings.py中设置MEDIA_ROOT和MEDIA_URL MEDIA_ROOT:一个绝对路径,Django根据它知道文件 ...

  6. open source e-business software - prestashop

    https://www.prestashop.com/en/system-requirements

  7. SQL Server之内连接 左连接 右连接 全连接 交叉连接

    SELECT * FROM Table_A GO SELECT * FROM Table_B GO --内连接 SELECT a.*, b.* FROM Table_A a JOIN Table_B ...

  8. compass做雪碧图

    由于最近没什么时间好好写博文,我把用sass做雪碧图的关键点贴出来方便自己记忆: config.rb注释 # Set this to the root of your project when dep ...

  9. 简单介绍AngularJs Filters

    网站链接:http://www.ncloud.hk/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/angular-filters/ Filter作用就是接收一个输入,通过某 ...

  10. hdu-5701 中位数计数(中位数)

    题目链接: 中位数计数 Problem Description   中位数定义为所有值从小到大排序后排在正中间的那个数,如果值有偶数个,通常取最中间的两个数值的平均数作为中位数. 现在有nn个数,每个 ...