最近在做一个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中新开一个线程操作 窗体上的控件(跨线程操作控件)的更多相关文章

  1. Python+Selenium练习篇之15-在浏览器中新开一个tab

    本文介绍如selenium方法打开一个新的tab,我们知道在浏览器里,我们按住 ctrl+ t 就可以新打开一个tab.所以我们学习如何利用webdriver中send_key 的方法去触发ctrl+ ...

  2. BeginInvoke 方法真的是新开一个线程进行异步调用吗?

    转自原文BeginInvoke 方法真的是新开一个线程进行异步调用吗? BeginInvoke 方法真的是新开一个线程进行异步调用吗? 参考以下代码: public delegate void tre ...

  3. java的服务是每收到一个请求就新开一个线程来处理吗?tomcat呢?

    首先,服务器的实现不止有这两种方式. 先谈谈题主说的这两种服务器模型: 1.收到一个请求就处理,这个时候就不能处理新的请求,这种为阻塞 这个是单线程模型,无法并发,一个请求没处理完服务器就会阻塞,不会 ...

  4. C#新开一个线程取到数据,如何更新到主线程UI上面

       一:问题 之前有被面试官问过,在WinForm中,要去网络上获取数据,由于网络环境等原因,不能很快的完成,因此会发生进程阻塞,造成主进程假死的现象,需要怎么解决?    二:思路 因此,往往是新 ...

  5. webdriver高级应用- 浏览器中新开标签页(Tab)

    #encoding=utf-8 import unittest from selenium import webdriver import time import win32api, win32con ...

  6. 在JNI中新开线程遇到问题

    08-03 13:39:30.535   1663-20490/system_process E/RfidReaderService﹕ input RDID CARD ID g_data:       ...

  7. Winform中怎样根据Name获取同窗体的控件

    场景 在同一个Winform窗体中,点击一个Button按钮时, 获取同窗体的其他控件的属性. 首先需要对要获取的控件赋予Name属性,然后就可以通过Name进行获取. 实现 在Button的点击事件 ...

  8. 实时刷新winform中的某一个控件上的文字

    需要注意的是,必须从UI线程,另外启动一个线程才可以. 在新线程调用异步刷新就OK了 Thread thread; private void button1_Click(object sender, ...

  9. PyCharm 项目打开窗口设置为当前还是新开一个怎么办?

     前言:       我找这个设置找了好久,后来在一篇博文中才找到,现在记录下来一下,顺便带图解释一下   设置步骤: File -> Setting -> Appearance & ...

随机推荐

  1. Event&Condition pyton

    Event 一个线程需要根据另外一个线程的状态来确定自己的下一步操作,需要调用threading库中Event对象:Event包含一个可由线程设置的信号标志,在初始情况下,event对象的标志位为假( ...

  2. OPENGL之矩阵

    前面的若干重要概念中描述了OPENGL中的几个重要变换,而矩阵是线性代数中的重要数学工具,它被用来对这些变换进行数学上的实现. 矩阵主要有以下几种: 模型视图矩阵:模型视图矩阵是个4*4的矩阵,代表经 ...

  3. Shiro-认证

    认证流程: 1. 获取当前的 Subject. 调用 SecurityUtils.getSubject();2. 测试当前的用户是否已经被认证. 即是否已经登录. 调用 Subject 的 isAut ...

  4. VMware“该虚拟机似乎正在使用中”问题

    在用VMware虚拟机的时候,有时会发现打开虚拟机时提示“该虚拟机似乎正在使用中.如果该虚拟机未在使用,请按“获取所有权(T)”按钮获取它的所有权.否则,请按“取消(C)”按钮以防损坏.配置文件: D ...

  5. 负载均衡下的资源文件配置/多站点下的资源文件夹共享(Windows IIS)

    前言: 负载均衡用的是NLB,微软的方案不太靠谱,举个例子吧,AB两台服务器负载出C,如果用户访问访问C之后分配的是A,那么如果A挂了,是不会自动切换到B的.据说后来还有一种NLB的方案可以实现,也不 ...

  6. Jenkins 2.x版本的节点配置选项更新

    [Dumb slave]改成了[Permanent Agent],效果一致 参考:http://serverfault.com/questions/793619/jenkins-trying-to-a ...

  7. C语言之函数可变参数

    先上一段代码: #include<cstdarg> #include<iostream> #include<string> using namespace std; ...

  8. Linux文件系统介绍(转)

    文章转自:http://www.iteye.com/topic/816268 文件系统是linux的一个十分基础的知识,同时也是学习linux的必备知识. 本文将站在一个较高的视图来了解linux的文 ...

  9. iptables实现正向代理

    拓扑图 实现目标 内网用户通过Firewall服务器(iptables实现)访问外网http服务 配置 #iptables iptables -t nat -A POSTROUTING -i eth0 ...

  10. 使用Scrapy爬虫框架简单爬取图片并保存本地(妹子图)

    初学Scrapy,实现爬取网络图片并保存本地功能 一.先看最终效果 保存在F:\pics文件夹下 二.安装scrapy 1.python的安装就不说了,我用的python2.7,执行命令pip ins ...