http://www.cnblogs.com/joey0210/p/3450379.html

最近在做一个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(){//执行一段费时的代码//......//线程中操作 控件,委托给invokerOpeMainFormControl(delegate(){this.lbl_loading_msg.Visible = false; //隐藏验证码加载中...的提示this.toolStripStatusLabel1.Text = ""; //清空状态栏this.btnlogin.Enabled = true;    //启用登录按钮
                });}));t.Start(); //启动线程

上面代码需要注意的是:仅对控件操作的代码委托给this.invoke。上面委托操作的方法中的this是窗体对象,也就是创建控件的线程,this.invoker(action)就是将代码交给它来执行。这样就操作控件的代码就交给了创建控件的线程来执行了。我们不要将费时操作的代码也交给this.invoker来执行,不然就失去了线程的意义了(相当于没有开线程)。this.invoke又回到了主线程,会产生阻塞!下面代码会阻塞:

                //将费时的代码也委托给 主线程(创建控件的线程)来执行,会阻塞窗体OpeMainFormControl(delegate(){//执行一段费时的代码//......//线程中操作 控件,委托给invokerthis.lbl_loading_msg.Visible = false; //隐藏验证码加载中...的提示this.toolStripStatusLabel1.Text = ""; //清空状态栏this.btnlogin.Enabled = true;    //启用登录按钮});

还有一点:如果对控件的操作代码没有委托给创建它的线程来执行(比如实例化另外一个窗口,show出来),它的一些设置会不起作用,比如:窗体初始显示位置等...

作者: 邹毅

WinForm中新开一个线程操作窗体上的控件(跨线程操作控件)GOOD相关推荐

  1. 一个http请求就是一个线程吗,java的服务是每收到一个请求就新开一个线程来处理吗...

    一个http请求就是一个线程吗,java的服务是每收到一个请求就新开一个线程来处理吗 答案是:是,一个http请求,就是一个线程. https://blog.csdn.net/elvis_lfc/ar ...

  2. SpringCloud工作笔记072---同一浏览器上不同标签页_tab页或者同一浏览器新开一个浏览器窗口也能实现单点登录_单点登录_localStorage_sessionStorage

    JAVA技术交流QQ群:170933152 注意用localStorage,存的token不会失效,可以在关闭浏览器的时候,清除或者设置一下过期时间,怎么做可以百度 注意:sessionStorage ...

  3. 软件测试面试题:在一个页面上,点击一个链接之后不会在当前页面上打开此链接而是新开一个窗口打开此页面。

    在一个页面上,点击一个链接之后不会在当前页面上打开此链接而是新开一个窗口打开此页面. Selenium也提供了对应的API来处理.简述这个查找新窗口的过程.参考答案:1)首先需要了解下,每个窗口都是有 ...

  4. Web: 使用Javascript新开一个浏览器标签而不是新开一个窗口

    很多浏览器对新开弹出窗口进行了限制,popup窗口在默认情况下会被block掉. 这样可能会造成按钮/链接/脚本不工作的假象. window.open("http:www.techbrood ...

  5. 浏览器中新开标签页(Tab)

    #!usr/bin/env python #-*- coding:utf-8 -*- """ ab @author: sleeping_cat @Contact : zw ...

  6. 手机通讯录中新加一个联系人,便会生成一个带姓氏的图片,这是如何实现的

    手机通讯录中新加一个联系人,便会生成一个带姓氏的图片,这是如何实现的 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页.如果你想学习如何使用Markdo ...

  7. 如何在label上显示字_如何地图上标注店面_新开的店铺要怎样上地图显示_怎么将公司标记在地图...

    新开的店铺商铺商家商户企业工厂怎么标注地图位置?如何地图上标注店面_怎么将店铺标记在地图_新开的店铺要怎样上地图显示?还没有办好营业执照可以做?您可能会有很多地图疑问?请直接联系腾图通地图服务公司为您 ...

  8. C#控件跨线程内容更新

    在使用C#开发winform应用程序时,经常会碰到对控件跨线程访问造成的异常.在winform中UI线程和工作线程是分开的,但在实际使用中经常会需要在工作线程更新UI线程中创建的控件. 方法1:禁用跨 ...

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

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

最新文章

  1. 贵州高二会考计算机考试题,20167月贵州普通高中学业水平考试会考试题
  2. deeplearning 重要调参参数分析
  3. 【模板】第二类斯特林数Stirling
  4. 如果测试你的MongoDB应用升级?
  5. C++总结笔记(五)——构造函数和析构函数
  6. 基于JAVA+SpringBoot+Mybatis+MYSQL的疫情信息管理系统
  7. Hibernate处理MySQL的时间
  8. 四:Cocos2d-x设计思想
  9. 从集合(内存)中创建RDD
  10. python怎么读取excel-python怎么读取excel中的数值
  11. matplotlib如何绘制两点间连线_python matplotlib 如何画点 而不要画点之间的连线?...
  12. docker配置阿里云镜像加速器
  13. ios 苹果支付(IAP)
  14. 计算机用固态硬盘无法启动不了,新固态硬盘装完系统无法进入解决教程
  15. matlab的h桥igbt驱动级死区电路,[转载]STM32 PWM死区--- H桥驱动电路 --- 三相桥式整流电路...
  16. CodeRunner激活
  17. windows10专业版镜像
  18. 清明出行之高德路况思考
  19. [Error] ld returned 1 exit status
  20. windows10共享移动热点(或说 电脑开WIFI),让手机连接共享的移动热点WIFI

热门文章

  1. 干货:图像比赛的通用套路有哪些?Kaggle比赛金牌团队为你解答
  2. go 注册登录 mysql_golang后台 实现用户登录注册
  3. 距离度量(Distance Metric)方法
  4. “创新驱动的结构化思维”培训
  5. 超详细,从零开始搭建阿里云服务器(centos7)第一章 远程连接
  6. 关于send和recv在UDP的使用
  7. 单元格的边框没有被显示出来
  8. Linux目录一个点.和两个点..的区别
  9. 福禄克FLUKE TIX650红外热像仪3.5英寸高像素大屏
  10. 货拉拉数据治理平台建设实践