可以参考”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. Collections.sort(List<T> Comparator) 自定义排序

    Collections.sort(basicinfoList, new Comparator<MlisBasicinfo>() { @Override public int compare ...

  2. Java项目经验——程序员成长的关键(转载)

    Java就是用来做项目的!Java的主要应用领域就是企业级的项目开发!要想从事企业级的项目开发,你必须掌握如下要点:1.掌握项目开发的基本步骤2.具备极强的面向对象的分析与设计技巧3.掌握用例驱动.以 ...

  3. 根据表结构自动生成JavaBean,史上最强最专业的表结构转JavaBean的工具(第2版)

             目录:                 第1版:http://blog.csdn.net/vipbooks/article/details/51912143              ...

  4. Java基础知识强化105:打印数组的方法总结

    1. 使用for循环打印数组. 2. 使用Arrays工具类,将数组转化为有序的List打印出来. 3. 使用Arrays工具类,使用Arrays.toString()输出数组内容. 上面三种方法打印 ...

  5. 重构12-Break Dependencies(打破依赖)

    有些单元测试需要恰当的测试“缝隙”(test seam)来模拟/隔离一些不想被测试的部分.如果你正想在代码中引入这种单元测试,那么今天介绍的重构就十分有用.在这个例子中,我们的客户端代码使用一个静态类 ...

  6. JAX-WS开发WebService程序

    近来公司里要用的到WebService做开发,所以就自己学习了一下,刚开始感觉挺难的,但是真正学会以后,原来这么简单. 今天把这些东西哦记下来,以便日后的复习. 我来介绍一下我的开发环境:Eclips ...

  7. css初接触

    一.简介:CSS 即 级联样式表 . 它是一种用来表现HTML(标准通用标记语言的一个应用)或XML(标准通用标记语言的一个子集)等文件样式的计算机语言. css是能够真正做到网页表现与内容分离的一种 ...

  8. VMware 命令行下的网络配置

    一般我们会在windows操作系统上安装VMware虚拟机,然后在虚拟机中安装Linux或Unix系统,但是我们很多人习惯了Windows系统的图形界面,换到Linux或Unix系统下不知道怎么配置网 ...

  9. Umbraco列表分页

    展示型文章经常会遇到分页的问题,以下是我的解决方法: ; ; int.TryParse(Request.QueryString["page"], out page); var to ...

  10. Java中创建操作文件和文件夹的工具类

    Java中创建操作文件和文件夹的工具类 FileUtils.java import java.io.BufferedInputStream; import java.io.BufferedOutput ...