C# 跨线程呼叫控制
在C# 应用程序开发, 我们经常要UI作线程分开,防止界面停止响应。 同一时候我们又须要在工作线程中更新UI界面上的控件,
以下介绍几种经常使用的方法
阅读文件夹
- 线程间操作无效
- 第一种办法:禁止编译器对跨线程訪问做检查
- 另外一种办法: 使用delegate和invoke来从其它线程中调用控件
- 第三种办法: 使用delegate和BeginInvoke来从其它线程中控制控件
- 第四种办法: 使用BackgroundWorker组件
- 源码下载
线程间操作无效
界面上有一个button和一个label, 点击button会启动一个线程来更新Label的值

private void button1_Click(object sender, EventArgs e)
{
Thread thread1 = new Thread(new ParameterizedThreadStart(UpdateLabel));
thread1.Start("更新Label");
} private void UpdateLabel(object str)
{
this.label1.Text = str.ToString();
}

执行后。 程序会报错 "跨线程操作无效,从不是创建"label1"的线程訪问它"

这是由于.NET禁止了跨线程调用控件。 否则谁都能够操作控件,最后可能造成错误。
以下介绍几种跨线程调用控件的方法
第一种办法:禁止编译器对跨线程訪问做检查
这是最简单的办法, 相当于不检查线程之间的冲突。同意各个线程随便乱搞,最后Lable1控件的值是什么就难以预料了 (不推荐使用这样的方法)
public Form1()
{
InitializeComponent();
// 增加这行
Control.CheckForIllegalCrossThreadCalls = false;
}
另外一种办法: 使用delegate和invoke来从其它线程中调用控件
调用控件的invoke方法。就能够控制控件了,比如

private void button2_Click(object sender, EventArgs e)
{
Thread thread1 = new Thread(new ParameterizedThreadStart(UpdateLabel2));
thread1.Start("更新Label");
} private void UpdateLabel2(object str)
{
if (label2.InvokeRequired)
{
// 当一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想訪问它
Action<string> actionDelegate = (x) => { this.label2.Text = x.ToString(); };
// 或者
// Action<string> actionDelegate = delegate(string txt) { this.label2.Text = txt; };
this.label2.Invoke(actionDelegate, str);
}
else
{
this.label2.Text = str.ToString();
}
}

第三种办法: 使用delegate和BeginInvoke来从其它线程中控制控件
仅仅要把上面的 this.label2.Invoke(actionDelegate, str); 中的 Invoke 改为BeginInvoke方法就能够了
Invoke方法和BeginInvoke方法的差别是
Invoke方法是同步的, 它会等待工作线程完毕。
BeginInvoke方法是异步的, 它会另起一个线程去完毕工作线程
第四种办法: 使用BackgroundWorker组件(推荐使用这种方法)
BackgroundWorker是.NET里面用来运行多线程任务的控件。它同意编程者在一个单独的线程上运行一些操作。耗时的操作(例如以下载和数据库事务)。
使用方法简单

private void button4_Click(object sender, EventArgs e)
{
using (BackgroundWorker bw = new BackgroundWorker())
{
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerAsync("Tank");
}
} void bw_DoWork(object sender, DoWorkEventArgs e)
{
// 这里是后台线程, 是在还有一个线程上完毕的
// 这里是真正做事的工作线程
// 能够在这里做一些费时的。复杂的操作
Thread.Sleep(5000);
e.Result = e.Argument + "工作线程完毕";
} void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//这时后台线程已经完毕。并返回了主线程。所以能够直接使用UI控件了
this.label4.Text = e.Result.ToString();
}

版权声明:本文博客原创文章。博客,未经同意,不得转载。
C# 跨线程呼叫控制的更多相关文章
- [WinForm]WinForm跨线程UI操作常用控件类大全
前言 在C#开发的WinForm窗体程序开发的时候,经常会使用多线程处理一些比较耗时之类的操作.不过会有一个问题:就是涉及到跨线程操作UI元素. 相信才开始接触的人一定会遇上这个问题. 为了解决这个问 ...
- c#中多线程同步Lock(锁)的研究以及跨线程UI的操作
本文只针对C#中,多线程同步所用到的锁(lock)作为研究对象.由于想更直观的显示结果,所以,在做demo的时候,就把多线程通过事件操作UI的代码也写了出来,留作备忘和分享吧. 其实多线程的同步,使用 ...
- winform 跨线程操作控件
当进行winform的开发时,经常遇到用时比较久的操作,在传统的单线程程序中,用户必须等待这个耗时操作完成以后才能进行下一步的操作,这个时候,多线程编程就派上用场了,将这个耗时的操作放到一个新的子线程 ...
- 扩展BindingList,防止增加、删除项时自动更新界面而不出现“跨线程操作界面控件 corss thread operation”异常
在做界面程序时,常常需要一些数据类,界面元素通过绑定等方式显示出数据,然而由于UI线程不是线程安全的,一般都需要通过Invoke等方式来调用界面控件.但对于数据绑定bindingList而言,没法响应 ...
- c#跨线程访问控件帮助类
1.背景 对于winform程序来说,当我们点击按钮,需要消耗一定时长才能拿到数据后才能显示在界面上某个控件上的情况,我们通常会专门开一个线程去拿数据,这样不会造成界面处于假死状态 2.常规做法 // ...
- WinForm中新开一个线程操作 窗体上的控件(跨线程操作控件)
最近在做一个winform的小软件(抢票的...).登录窗体要从远程web页面获取一些数据,为了不阻塞登录窗体的显示,开了一个线程去加载数据远程的数据,会报一个错误"线程间操作无效: 从不是 ...
- C#跨线程操作控件
1.首先通过按键创建子线程: 创建子线程,子线程调用changeText方法. private void btnOK_Click(object sender, EventArgs e) { Threa ...
- 简短总结一下C#里跨线程更新UI(转)
摘自: http://my.oschina.net/sdqxcxh/blog/53707 跨线程更新UI是写多线程程序尤其是通信类的程序经常遇到的问题,这里面主要的问题是冲突,比如数据线程想要更新UI ...
- C# 跨线程调用控件
在C# 的应用程序开发中, 我们经常要把UI线程和工作线程分开,防止界面停止响应. 同时我们又需要在工作线程中更新UI界面上的控件, 下面介绍几种常用的方法 阅读目录 线程间操作无效 第一种办法:禁 ...
随机推荐
- HTML5之Canvas影片广场
HTML5之Canvas影片广场 1.设计源代码 <!DOCTYPE html> <head> <meta charset="utf-8" /> ...
- redis预切片技术,实现
平时,我们将创建多个redis实例,以缓解单redis压力范例.但,作为高速缓存的数量增加.对redis对于扩展是一种非 - 不要无所谓.对redis有几种方法用于扩张可能.让我们添加每个redis最 ...
- 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern)
原文:乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) 作者:weba ...
- 2015广东工业大学ACM学校巡回赛 I 游戏高手 (如压力dp)
Problem I: 游戏王 Description 小学的时候,Stubird很喜欢玩游戏王.有一天,他发现了一个绝佳的连锁组合,这个连锁组合须要6张卡. 但是他一张都没有,但是他的那些朋友们有.只 ...
- CodeCounter代码统计
今天一天写的,困死了 开发环境:VS2012 + WIN8-x64, MFC CSDN下载链接:http://download.csdn.net/detail/npu_wy/7405577 百度云下载 ...
- WWDC 2014 Session 205/217 Extension 注意事项
基于阅读下面的内容205和217的PDF做笔记.没有深入研究. 205 Creating Extensions for iOS and OS X, Part 1 217 Creating Extens ...
- mfc 链接时错误 文件函数重复定义
我在HeaderFile里新建了一个函数,然后在程序里调用,一直出现这个错误,说这个函数重复定义, 发现是VS自动加到External dependencies里面了.把HeaderFile里的函数文 ...
- 当向后台插入或读取JSON数据遇见回车时
今天在项目中发现.当插入或读取JSON数据时遇见回车符.返回JSON数据格式时会报错(firebug里体现为乱码),百度了一下发现JSON不支持字符串里存在回车! 解决的方法: 在向接口插入带json ...
- HDU 1596 find the safest road (最短路)
find the safest road Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- dom 规划(html和xml)
html dom与xml dom关联: 什么是 DOM? DOM 是 W3C(万维网联盟)的标准. DOM 定义了訪问 HTML 和 XML 文档的标准: "W3C 文档对象模型 (DOM) ...