最近在做一个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. VisualSVN Server HTTPS

    目测windows平台当前搭建svn最简单的就是VisualSVN Server 启动https 证书cp下面目录 C:\Program Files\VisualSVN Server\certs 修改 ...

  2. Leetcode Power of two, three, four

    Given an integer, write a function to determine if it is a power of two. Hint: Could you solve it in ...

  3. CLR/.NET/C#/Visual Studio/ASP.NET各版本之间的关系(转)

    由于这篇文章记录的是2015年7月,那时.net core还是叫做.net core 5 名词定义 下列这些名词,写.NET 的人一定都不陌生,但你是否有真正理解呢?如果看了我的摘要文字说明还无法理解 ...

  4. SQL Server 2008及以上版本出现”SQL Server 复制需要有实际的服务器名称才能连接到服务器...“的问题解决

    出现如下错误: 这是由于安装时的计算机名更改导致会出现如上的错误. 解决方法: 1.SQL方式: 1)先执行如下脚本,看下名称是否一致 use master go select @@servernam ...

  5. 组合数取模Lucas定理及快速幂取模

    组合数取模就是求的值,根据,和的取值范围不同,采取的方法也不一样. 下面,我们来看常见的两种取值情况(m.n在64位整数型范围内) (1)  , 此时较简单,在O(n2)可承受的情况下组合数的计算可以 ...

  6. Python Twisted、Reactor

    catalogue . Twisted理论基础 . 异步编程模式与Reactor . Twisted网络编程 . reactor进程管理编程 . Twisted并发连接 1. Twisted理论基础 ...

  7. 导入.pch文件

    Xcode5中创建一个工程的时候,系统会自动创建一个以以工程名为名字的pch(Precompile Prefix Header)文件,开发的过程中可以将广泛使用的头文件以及宏包含在该文件下,编译器就会 ...

  8. css002 创建样式和样式表

    创建样式和样式表 一个样式表包含多个样式 样式表的种类 1.内部样式表,存放在<head></head>之间.如: <head> <style>   ( ...

  9. sql 分页的两种写法

    string Strsql = string.Format(@"select ee.DOCUMENTNO,ee.APPLICANTNAME,ee.COMPANY,ee.REQUESTTIME ...

  10. pyqt2_官网教程

    https://pythonspot.com/en/pyqt4/ Articles You can find a collection of PyQT articles below. Applicat ...