• C# 在子线程中创建不会阻塞执行窗体


    可以参考”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. }
    6.  

    (2) 线程入口函数

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

    (3) 创建,并执行线程

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

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

    执行结果如下:

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

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

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

  • 相关阅读:
    mysql索引
    mysql中的事务
    mysql的各种join连接
    java集合-LinkedList源码分析
    java集合(二)-ArrayList源码分析
    java集合(一)-集合概述
    java并发(五)-重排序、 happens-before
    vue引入百度地图 --BMap is not defined ,eslint BMap报错
    红星美凯龙前端面试内容总结
    vue父子组件钩子函数的执行顺序
  • 原文地址:https://www.cnblogs.com/ITyouxiang1994/p/4220895.html
Copyright © 2020-2023  润新知