当前位置: 首页 > 编程日记 > 正文

c#中如何跨线程调用windows窗体控件?

我们在做winform应用的时候,大部分情况下都会碰到使用多线程控制界面上控件信息的问题。然而我们并不能用传统方法来做这个问题,下面我将详细的介绍。
首先来看传统方法:

复制代码
      public partial class Form1 : Form{public Form1(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){Thread thread = new Thread(ThreadFuntion);thread.IsBackground = true;thread.Start();}private void ThreadFuntion(){while (true){this.textBox1.Text = DateTime.Now.ToString();Thread.Sleep(1000);}}}
复制代码

运行这段代码,我们会看到系统抛出一个异常:

Cross-thread operation not valid:Control 'textBox1' accessed from a thread other than the thread it was created on .

这是因为.net 2.0以后加强了安全机制,不允许在winform中直接跨线程访问控件的属性。那么怎么解决这个问题呢,下面提供几种方案。
第一种方案,我们在Form1_Load()方法中加一句代码:

复制代码
      private void Form1_Load(object sender, EventArgs e){Control.CheckForIllegalCrossThreadCalls = false;Thread thread = new Thread(ThreadFuntion);thread.IsBackground = true;thread.Start();}
复制代码

加入这句代码以后发现程序可以正常运行了。这句代码就是说在这个类中我们不检查跨线程的调用是否合法(如果没有加这句话运行也没有异常,那么说明系统以及默认的采用了不检查的方式)。然而,这种方法不可取。我们查看CheckForIllegalCrossThreadCalls 这个属性的定义,就会发现它是一个static的,也就是说无论我们在项目的什么地方修改了这个值,他就会在全局起作用。而且像这种跨线程访问是否存在异常,我们通常都会去检查。如果项目中其他人修改了这个属性,那么我们的方案就失败了,我们要采取另外的方案。
      下面来看第二种方案,就是使用delegate和invoke来从其他线程中控制控件信息。网上有很多人写了这种控制方式,然而我看了很多这种帖子,表明上看来是没有什么问题的,但是实际上并没有解决这个问题,首先来看网络上的那种不完善的方式:

复制代码
    public partial class Form1 : Form{private delegate void FlushClient();//代理public Form1(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){Thread thread = new Thread(CrossThreadFlush);thread.IsBackground=true;thread.Start();}private void CrossThreadFlush(){//将代理绑定到方法FlushClient fc = new FlushClient(ThreadFuntion);this.BeginInvoke(fc);//调用代理}private void ThreadFuntion(){while (true){this.textBox1.Text = DateTime.Now.ToString();Thread.Sleep(1000);}}}
复制代码

使用这种方式我们可以看到跨线程访问的异常没有了。但是新问题出现了,界面没有响应了。为什么会出现这个问题,我们只是让新开的线程无限循环刷新,理论上应该不会对主线程产生影响的。其实不然,这种方式其实相当于把这个新开的线程“注入”到了主控制线程中,它取得了主线程的控制。只要这个线程不返回,那么主线程将永远都无法响应。就算新开的线程中不使用无限循环,使可以返回了。这种方式的使用多线程也失去了它本来的意义。
现在来让我们看看推荐的解决方案

复制代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;namespace WindowsFormsApplication4
{public partial class Form1 : Form{private delegate void FlushClient(); //代理Thread thread = null;int counter = 0;public Form1(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){this.listBox1.Items.Clear();button1.Enabled = false;thread = new Thread(CrossThreadFlush);thread.IsBackground = true;thread.Start();}private void button2_Click(object sender, EventArgs e){thread.Suspend();button1.Enabled = true;}private void CrossThreadFlush(){while (true){//将sleep和无限循环放在等待异步的外面Thread.Sleep(1000);ThreadFunction();}}private void ThreadFunction(){if (this.listBox1.InvokeRequired)//等待异步{FlushClient fc = new FlushClient(ThreadFunction);this.Invoke(fc); //通过代理调用刷新方法}else{counter += 1;this.label1.Text = counter.ToString();this.listBox1.Items.Add(System.DateTime.Now.ToString());}}}
}
复制代码

运行上述代码,我们可以看到问题已经被解决了,通过等待异步,我们就不会总是持有主线程的控制,这样就可以在不发生跨线程调用异常的情况下完成多线程对winform多线程控件的控制了。

原文:http://www.cnblogs.com/zhaotiantang/archive/2009/03/17/1414135.html

转载于:https://www.cnblogs.com/darksoulson/p/3428577.html

相关文章:

poj 1964 Cow Cycling(dp)

/* 一开始想的二维的 只维护第几只牛还有圈数 后来发现每只牛的能量是跟随每个状态的 所以再加一维 f[i][j][k]表示第i只牛 领跑的j全 已经消耗了k体力 转移的话分两类 1.换一只牛领跑 那么就从f[i][j][k]转移到f[i1][j][j] 2.不换 那就枚举i领跑几圈l f[i][j-l][k-l*l]转移到…

高级网络配置《 bond team桥接 》的建立

bond 资料详情 一、链路聚合:以太网链路聚合简称链路聚合,它通过将多条以太网物理链路捆绑在一起成为一条逻辑链路,从而实现增加链路带宽的目的。同时,这些捆绑在一起的链路通过相互间的动态备份,可以有效地提高链路…

iOS通过CAShapeLayer和UIBezierPath画环形进度条

UIBezierPath可以绘制矢量路径,而CAShapeLayer是Layer的子类,可以在屏幕进行绘制,本文主要思想是:CAShapeLayer按照UIBezierPath的矢量路径进行绘制。 效果图如图: 方法如下: interface ViewController ()…

这些云计算技术你了解过哪几种

新霸哥发现目前信息量高速增长的今天,IT行业正在面临着空间和成本等资源的巨大压力,但是随着这些需求的日益增长,在行业中出现了一类全新的解决方案,通过云计算技术对数据中心进行改造。要获得云计算的优势,必须在it基…

Tomcat官方文档关于数据源配置的内容

虽然有网上有网友自己总结的文章,但说明得总是不够清晰,还是参考官方文档理解得比较透彻: http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html http://tomcat.apache.org/tomcat-7.0-doc/jndi-datasource-examples-howto.html 转载于:h…

利用kickstart自动安装虚拟机

虚拟机的手动安装 下载dhcp服务 systemctl stop firewalld getenforce setenforce 0 关闭防火墙 图中最后面添加一个 } yum install systemctl-4.05-8.el7.x86_64 rpm -ql syslinux rpm -ql tftp-server 在挂载…

第17章 使用iSCSI服务部署网络存储

章节概述: 本章节将分析SCSI与iSCSI技术结构的不同,了解iSCSI技术的优势、SAN存储网络技术结构以及iSCSI HBA卡的作用。 完整演示部署iSCSI target服务程序的方法流程:创建RAID阵列(5)后使用targetcli命令发布到iSCSI存储目录并创建ACL列表。…

【仿去哪儿】骆驼动画加载

简单的实现正在加载的动画,比较粗糙,没有实现后面的旋转地球。图一为去哪儿的截图,图二为本文实现的效果 图1 图2 一、新建LoadView继承自UIView,声明几个方法,这样在项目需要用到时,直接调用就行&#xff…

来自极客标签10款最新设计素材-系列十六

本周我们推荐来自极客标签社区带来的10款免费设计素材,大家可以在这里免费下载你需要的内容。如果你也有更好的作品,欢迎分享到社区中来,在得到帮助的同时,也能与更多人分享来自你的作品。 免费图标:扁平风格的图标集…

python简介、安装及基本设置

python简介 1、Python的定义: Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有比其他语言更有特色…

MVC会员注册

自从写了《数据库数据加密与解密》http://www.cnblogs.com/insus/p/3434735.html。其中也有提及Insus.NET将要在MVC应用程序中实现会员注册的功能。一段时间来,工作繁忙,这个星六还要值班。现在算是忙里偷闲,继续写MVC的程序。本次要实现会员…

继承,基类,派生类

在 C中,继承机制通过类的派生实现,被继承的类称为基类或父类;在继承类的基础上创建的新类称为派生类或子类。派生类的定义格式为:class 派生类名:继承方式基类名 1,继承方式基类名 2,…,继承方式基类名 n{派生类增加的成员声明;};…

【仿去哪儿】滑动隐藏导航栏

仿照去哪儿,隐藏导航栏(其实是设置为透明背景):向下滑动到时,当顶部图片看不见时,显示导航栏,源代码下载,效果如下: 主要思想:就是监听UITableView的滑动事件…

Python基本知识以及if语句

注释 什么时候需要注释? 对于复杂的操作,应该在操作开始前写若干行注释,目的是增加可读性,注释应该和代码至少离开两个空格 单行注释(两种方式) 多行注释(一种方式) ####if语句&…

通过pip安装模块

环境:ubuntu,python2/3 命令: pip3 install ipy  # 通过pip3给python3.x安装ipypip3 install --upgrade pip  # 升级pippip install ipy  # 通过pip给python2.x安装ipy 如果显示程序“pip/pip3”尚未安装 sudo apt-get install python3…

按照文字内容动态设置TableViewCell的高度

最近再做个项目需要使用UITableView来显示评论列表,但是有的评论字数特别多,固定的Cell高度显示不完,只能动态地根据字数来设置Cell的高度了 只要实现UITableViewDelegate的 -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIn…

分享十款免费数据恢复软件

绝大多数的数据恢复软件都可以帮助你恢复被删除的文件。免费数据恢复软件可帮助你“取消删除”或者恢复电脑中的文件。那些你已经删除而且最近从回收站清空的文件仍然存在硬盘上(或介质卡或USB驱动器等),也可以通过这些免费数据恢复软件轻松地…

Python 字符串及基本语句

#####1、break break: 某一条件满足的时候&#xff0c;退出循环&#xff0c;不再执行后续重复的代码 在循环体内部&#xff0c;我们可以增加额外的条件&#xff0c;在需要的时候&#xff0c;跳出整个循环 i 0 while i <10: if i 3: break print i i 1 print ‘over’ #…

javascript 方法实例

输出对象的属性名称与值 &#xff1a; boj(o){for(var p in o){console.log(p ":" o[p] "\n"); } } 构造函数&#xff1a; var o new Object(); 构造函数通过不使用return关键字&#xff0c;它通过初始化新对象 if(a)else{b} //如果不是a就返…

ISAPI在IIS7上的配置

主要介绍ISAPI的作用、ISAPI在IIS7上的配置、开发ISAPI的基本内容及使用VS 2008配置ISAPI DLL开发项目。 一、ISAPI介绍 缩写词Internet Server Application Programming Interface为Microsoft所提的Internet server的API 。 ISAPI分为两种&#xff1a;ISAPI extension &#x…

iOS自定义转场动画

图1是最近闲着做的一个项目&#xff1a;午睡闹钟&#xff08;欢迎到AppStore下载&#xff0c;截稿时最新版还在审核&#xff09;的截图&#xff0c;把其中的转场动画效果简单封装了一下写了个demo&#xff08;图2&#xff09;&#xff0c;demo的备注写的比较清楚&#xff0c;de…

Python中if语句练习题

####1、#####if-else语句 #elif和else都必须和if联合使用&#xff0c;不能单独使用 holidy_name 中秋节 if holidy_name 情人节: print 买玫瑰 print 看电影 elif holidy_name 圣诞节: print 吃大餐 elif holidy_name 生日: print 吃蛋糕 print 买礼…

开源:ASP.NET MVC+EF6+Bootstrap开发框架

前言 我在博客园潜水两三年了&#xff0c;在这里看过很多大神的文章&#xff0c;也学到了很多东西。可以说我是汲取着博客园的营养成长的。 想当年&#xff0c;我也是拿10个G的精神粮食从一个博客园大神那里换来一套开发框架&#xff0c;正式走上开发之路&#xff0c;到后来成为…

【iOS官方文档翻译】iOS的蓝牙连接、数据接收及发送

说明&#xff1a;苹果官方开发文档中涉及一些名词&#xff1a;Central&#xff08;中心设备&#xff09;、Peripheral&#xff08;外围设备&#xff09;、advertising&#xff08;广告&#xff09;、Services&#xff08;服务&#xff09;、Characteristic&#xff08;特征&…

checkbox全选与反选

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><title>全选与反选</title><meta http-equiv"Content-Type" content"text/html;…

元组、列表及其特性

1、 #元组&#xff1a;带了紧箍咒的列表&#xff0c;不可直接修改元组内容 #元组本身不可变数据类型&#xff0c;没有增删改差 #元组内可以存储任意数据类型 t(1,2,3,4.2,star) print t,type(t) #元组内包含可变数组类型&#xff0c;可以间接修改元组内容 t1([1,2,3.3],4,5)…

JZOJ #4722 跳楼机 (最短路模型的完美转化)

题目描述&#xff1a; 给出$h,x,y,z$&#xff0c;求在$h$以内&#xff0c;$x,y,z$可以凑出多少个不同的数。$(1\leq{h}\leq{10^{18}},1\leq{x,y,z}\leq{10^5})$ 解题思路&#xff1a; 直接做显然不好做。我们考虑取$n$个$y$和$m$个$z$&#xff0c;然后再加上$x,2*x,3*x\cdots$&…

【C++】STL队列和栈的使用

C的STL标准模板库提供了队列和栈的基本操作。下面通过两个demo分别介绍STL队列和STL栈的使用。 Demo1&#xff1a;STL队列 【题目】卡片游戏&#xff08;题目来自刘汝佳《算法竞赛入门》&#xff09; 桌上又一叠牌&#xff0c;从第一张牌&#xff08;即位于顶面的牌&#xf…

mongodb的shell命令

MongoDB常用命令&#xff1a; 超级用户相关&#xff1a; use admin #增加或修改用户密码 db.addUser(ixigua,pwd) #查看用户列表 db.system.users.find() #用户认证 db.auth(ixigua,pwd) #删除用户 db.removeUser(mongodb) #查看所有用户 show users #查看所有数据库 show dbs …

字典、集合及其特性

1、 字典的定义 """ 字典是一个无序的数据集合&#xff0c;使用print输出字典的时候 通常输出的顺序和定义的顺序是不一致的 """ message { name:tom, age:18, height:1.80, weight:75.5 } print message s {} prin…