WinForm中新开一个线程操作 窗体上的控件(跨线程操作控件)
最近在做一个winform的小软件(抢票的...)。登录窗体要从远程web页面获取一些数据,为了不阻塞登录窗体的显示,开了一个线程去加载数据远程的数据,会报一个错误"线程间操作无效: 从不是创建控件“lbl_loading_msg”的线程访问它。"百度一下,原来从.net framework 2.0开始,为了安全,不允许跨线程操作控件。解决办法如下:
1、声明一个拥有委托类型的方法,作为代理 操作控件的代码:
/// <summary>
/// 在线程中操作窗体的控件
/// </summary>
/// <param name="action"></param>
private void OpeMainFormControl(Action action)
{
if (this.InvokeRequired)
{
this.Invoke(action); //返回主线程(创建控件的线程)
}
else
{
action();
}
}
2、然后在线程中,只要是对控件的操作都委托给上面的方法执行,不管是读取还是赋值:
Thread t = new Thread(new ThreadStart(delegate()
{
//执行一段费时的代码
//......
//线程中操作 控件,委托给invoker
OpeMainFormControl(delegate()
{
this.lbl_loading_msg.Visible = false; //隐藏验证码加载中...的提示
this.toolStripStatusLabel1.Text = ""; //清空状态栏
this.btnlogin.Enabled = true; //启用登录按钮
});
}));
t.Start(); //启动线程
上面代码需要注意的是:仅对控件操作的代码委托给this.invoker。上面委托操作的方法中的this是窗体对象,也就是创建控件的线程,this.invoker(action)就是将代码交给它来执行。这样就操作控件的代码就交给了创建控件的线程来执行了。我们不要将费时操作的代码也交给this.invoker来执行,不然就失去了线程的意义了(相当于没有开线程)。this.inoker又回到了主线程,会产生阻塞!下面代码会阻塞:
//将费时的代码也委托给 主线程(创建控件的线程)来执行,会阻塞窗体
OpeMainFormControl(delegate()
{
//执行一段费时的代码
//......
//线程中操作 控件,委托给invoker this.lbl_loading_msg.Visible = false; //隐藏验证码加载中...的提示
this.toolStripStatusLabel1.Text = ""; //清空状态栏
this.btnlogin.Enabled = true; //启用登录按钮
});
还有一点:如果对控件的操作代码没有委托给创建它的线程来执行(比如实例化另外一个窗口,show出来),它的一些设置会不起作用,比如:窗体初始显示位置等...
WinForm中新开一个线程操作 窗体上的控件(跨线程操作控件)的更多相关文章
- Python+Selenium练习篇之15-在浏览器中新开一个tab
本文介绍如selenium方法打开一个新的tab,我们知道在浏览器里,我们按住 ctrl+ t 就可以新打开一个tab.所以我们学习如何利用webdriver中send_key 的方法去触发ctrl+ ...
- BeginInvoke 方法真的是新开一个线程进行异步调用吗?
转自原文BeginInvoke 方法真的是新开一个线程进行异步调用吗? BeginInvoke 方法真的是新开一个线程进行异步调用吗? 参考以下代码: public delegate void tre ...
- java的服务是每收到一个请求就新开一个线程来处理吗?tomcat呢?
首先,服务器的实现不止有这两种方式. 先谈谈题主说的这两种服务器模型: 1.收到一个请求就处理,这个时候就不能处理新的请求,这种为阻塞 这个是单线程模型,无法并发,一个请求没处理完服务器就会阻塞,不会 ...
- C#新开一个线程取到数据,如何更新到主线程UI上面
一:问题 之前有被面试官问过,在WinForm中,要去网络上获取数据,由于网络环境等原因,不能很快的完成,因此会发生进程阻塞,造成主进程假死的现象,需要怎么解决? 二:思路 因此,往往是新 ...
- webdriver高级应用- 浏览器中新开标签页(Tab)
#encoding=utf-8 import unittest from selenium import webdriver import time import win32api, win32con ...
- 在JNI中新开线程遇到问题
08-03 13:39:30.535 1663-20490/system_process E/RfidReaderService﹕ input RDID CARD ID g_data: ...
- Winform中怎样根据Name获取同窗体的控件
场景 在同一个Winform窗体中,点击一个Button按钮时, 获取同窗体的其他控件的属性. 首先需要对要获取的控件赋予Name属性,然后就可以通过Name进行获取. 实现 在Button的点击事件 ...
- 实时刷新winform中的某一个控件上的文字
需要注意的是,必须从UI线程,另外启动一个线程才可以. 在新线程调用异步刷新就OK了 Thread thread; private void button1_Click(object sender, ...
- PyCharm 项目打开窗口设置为当前还是新开一个怎么办?
前言: 我找这个设置找了好久,后来在一篇博文中才找到,现在记录下来一下,顺便带图解释一下 设置步骤: File -> Setting -> Appearance & ...
随机推荐
- 浏览器上网 (Safari & Chrome)
浏览器上网 (Safari & Chrome) Command + L = 光标移到地址框 Command + R = 刷新页面 Command + + = 大屏幕的时候很实用,放大页面,基本 ...
- js-JavaScript高级程序设计学习笔记13
第十五章 canvas绘图 1.WebGL是针对Canvas的3D上下文. 2.类型化数组 WebGL涉及的复杂计算需要提前知道数值的精度,而标准的JS数值无法满足需求.因此WebGL引入了一个概念, ...
- 向列布局动态添加F7
function initBuildingEntryF7(sellId){ var comId = "buildingEntry"; var filter = "&quo ...
- squid安装配置
Squid做反向代理(192.168.1.69) squid.conf http_port 80 vhost vport visible_hostname pdd2.matrixcdn.net cac ...
- Unity 联网小测试(WWW)
研究了很多联网的方式,甚至把TCP/IP,shock,HTTP的关系都搞清楚了,终于弄明白怎么在Unity中用GET或POST的方式通信了,还是有点小激动的,但是不排除有更好的方式,听说Unity还是 ...
- C#获取外网IP
思路是通过WebRequest连接一些网上提供IP查询服务的网站,下载到含有你的IP的网页,然后用正则表达式提取出IP来 class Program { static void Main(string ...
- BeautifulSoup高级应用 之 CSS selectors /CSS 选择器
BeautifulSoup支持最常用的CSS selectors,这是将字符串转化为Tag对象或者BeautifulSoup自身的.select()方法. 本篇所使用的html为: html_doc ...
- hibernate-聚合函数分组统计数据查询
聚合函数: 实例: package Test; import static org.junit.Assert.*; import java.util.List; import org.hibernat ...
- oracle建表并设置ID为自动增长
CREATE TABLESPACE shopping DATAFILE 'D:\oracle\mypc\oradata\orcl\shopping.dbf' SIZE 20M AUTOEXTEND O ...
- JavaWeb学习总结-01 JavaWeb开发入门
一 基本概念 1 Web开发的相关知识 Web,表示网页的意思,它用于表示Internet主机上供外界访问的资源. Internet上供外界访问的Web资源分为: 静态web资源(如html 页面): ...