在WinForm项目中,我们通常会采用界面逻辑分离,由逻辑线程触发的对界面控件的操作,会因为跨线程导致各种问题,那么是否有一种通用操作,来解决我们在日常开发遇到的这种问题呢?

我所遇到的具体问题如下:当前有两条线程,线程1为UI线程,所有UI都在此线程中初始化,线程2为消息线程,通常情况下线程2是阻塞的,但是我们必须要在线程2中触发对界面的操作,比如登录结束后,收到login_res,需要隐藏登录界面并且展示主界面。当我在线程2中操纵界面显示的时候,会由于线程2自己的阻塞导致主界面加载到一半便会卡死。此时做线程输出,会发现对界面的操作一直是在线程2上的,即使我强制调用界面的refresh方法刷新界面,也会由于线程的阻塞导致后续界面一直是卡死状态

理所当然的,我们会想到Contral的Invoke。那么接下来,结合我的框架聊一下我的设计。

我的架构采用界面-界面控制-逻辑三层,其中界面控制层提供一系列的委托,提供给逻辑层调用

首先由于我使用的界面并不多,这里我们以登录界面和创角界面来做展示,运行逻辑为:程序开始时创建登录界面,玩家输入账号密码,点击确认后向服务器发送login_req,当服务器检测到没有此账号,便会在login_res中携带一个标识,当消息线程读取到此标识后,会打开创角界面。

下面是登录界面的构造函数

 public LoginForm()//登录界面,于程序开始时初始化{InitializeComponent();//界面初始化if (MyClient.SFlag == 1)//对与服务器的连接状体做输出{this.label_connect.Text = "连接状态:已连接";}Control.CheckForIllegalCrossThreadCalls = false;//允许其他线程操作界面//在这里初始化界面,此时是在UI线程中初始化GameFrame.formContral.hideLogin = new FormDelegate(hideLogin);CreatForm cf = new CreatForm();//这一步很关键,需要调用界面Show方法,才可以在当前线程创建界面句柄cf.Show();cf.Hide();}

下面是创角界面的构造函数

      public CreatForm(){InitializeComponent();//界面初始化Control.CheckForIllegalCrossThreadCalls = false;//允许跨线程访问(可以不加)GameFrame.formContral.showCreate = new FormDelegate(showForm);//将构该界面中对界面的操作封装成方法交给委托}

下面是创角界面在消息线程上被调用的方法

public void showForm(){OpeMainFormControl(delegate (){this.Show();});}private void OpeMainFormControl(Action action){if (this.InvokeRequired){this.Invoke(action); //返回主线程(创建控件的线程)}else{action();}}
}

首先,这里需要用到控件的Invoke,它可以将对控件的操作委托回控件创建的线程进行操作,这样就解决了跨线程调用的线程安全问题,并且,这个方法是在消息线程中调用,消息线程总是阻塞的。
这里有一点需要特别注意,如果在界面创建的线程上没有调用界面的Show方法,那么是不会在改线程上创建界面的句柄,那么"this.InvokeRequired"的值为false,此时无法invoke!

WinForm中跨线程修改界面控件相关推荐

  1. java 线程访问控件_C#多线程与跨线程访问界面控件的方法

    本文实例讲述了C#多线程与跨线程访问界面控件的方法.分享给大家供大家参考.具体分析如下: 在编写WinForm访问WebService时,常会遇到因为网络延迟造成界面卡死的现象.启用新线程去访问Web ...

  2. C# Winform 跨线程更新UI控件常用方法汇总(多线程访问UI控件)

    概述 C#Winform编程中,跨线程直接更新UI控件的做法是不正确的,会时常出现"线程间操作无效: 从不是创建控件的线程访问它"的异常.处理跨线程更新Winform UI控件常用 ...

  3. 日积(Running)月累(ZSSURE):WCF学习之“通过事件绑定控制WinForm宿主程序主界面控件”

    背景: WCF服务需要寄宿到相应的可运行进程中执行,常见的有四种寄宿,分别是控制台程序.WinForm程序.IIS和Windows服务.之前学习老A博客和<WCF全面解析>时最常用到的是控 ...

  4. C# WinForm跨线程访问UI控件

    C# 跨线程访问控件 在做WinForm时,在UI线程之外调用控件会报异常:System.InvalidOperationException:"线程间操作无效: 从不是创建控件"l ...

  5. WinForm 简易仿360界面控件

    因为经常要做一些1.2千行的小工具,WinForm自带的TabCtrl又不美观,所以想做成360的样子,在网上找来找去,都只有散乱的代码,没有可以通用的结构,于是自己写了一个简易的通用控件. 控件主要 ...

  6. wxpython后台如何更新界面信息_wxpython后台线程更新界面控件方法

    在大多数的GUI应用程序中,在应用程序的后台中长期执行一个处理过程而不干涉用户与应用程序的其它部分的交互是有好处的.允许后台处理的机制通常是产生一个线程并在该线程中长期执行一个处理过程.对于wxPyt ...

  7. wxpython后台线程更新界面控件方法

    http://blog.sina.com.cn/s/blog_56146dc501009ea9.html http://www.th7.cn/Program/Python/201303/128088. ...

  8. C# winform 跨线程修改界面

    我们可以使用invoke和bengininvoke invoke同步执行一个委托 begininvoke异步执行一个委托 转载于:https://www.cnblogs.com/birdofparad ...

  9. C#-WinForm跨线程修改UI界面

    背景 在我做WinForm开发的过程中,经常会遇到耗时操作或阻塞操作.他们会引发软件的卡顿甚至假死,严重影响软件的使用.因此,这类耗时或阻塞的操作一般都会使用异步的方式去执行,不影响主线程(UI线程) ...

  10. InvokeHelper,让跨线程访问/修改主界面控件不再麻烦(转)

    http://bbs.csdn.net/topics/390162519 事实上,本文内容很简单且浅显,所以取消前戏,直接开始.. 源代码:在本文最后 这里是一张动画,演示在多线程(无限循环+Thre ...

最新文章

  1. ubuntu 防火墙打开关闭
  2. centos部署python个人博客项目
  3. SQL优化技巧--远程连接对象引起的CTE性能问题
  4. 一个div 上下两行_web前端工程师如何理解 CSS 布局和块级格式化上下文
  5. 开关电源PCB排版基本要点概述
  6. js与c语言效率_2020年为什么要精通C语言?是什么造就封神之路?不愧是最强编程语言...
  7. mysql 什么时候用内连接_mysql显示内连接和隐式内连接的区别,什么时候非要用到显示内连接。...
  8. 基于深度强化学习的路径规划笔记
  9. python日常练习五,PPT批量转化pdf,批量把Word存入excel
  10. Oracle SOA平台1——概述
  11. 三分钟教你学Git(十二) 之 fast-forward
  12. 使用PyInstaller脚本打包时提示Unable to open icon file 的一种情况
  13. 渗透测试实习日记day1
  14. 一次zookeeper启动失败的解决过程
  15. 一、使用JDK的keytool生成JKS以及获取JKS的信息
  16. Nature子刊:机器学习方法扩展了anti-CRISPR蛋白家族的所有成员
  17. 网络空间安全竞赛D模块解析
  18. python文件练习题
  19. 【文档】AOA-with-DW1000_V1.1
  20. [碎碎念]来谈谈写作这件事

热门文章

  1. 元宵节“最强大脑”,这些灯谜难倒了99%的互联网人!
  2. 混合云这个砝码到底有多重?
  3. modelsim10.5-se安装包
  4. 正人先正己,做事先做人
  5. 浅谈人文社科与自然科学间的方法论鸿沟
  6. nginx 面试宝典
  7. 定义变/常量和变量的初始化
  8. eclipse代码背景块出现红色问题
  9. 过早的优化是万恶之源?
  10. OpenWrt 广告植入原型搭建