C#多线程编程总结
VS2008、C#3.0
在WinForm开发中,我们通常不希望当窗体上点了某个按钮执行某个业务的时候,窗体就被卡死了,直到该业务执行完毕后才缓过来。一个最直接的方法便是使用多线程。多线程编程的方式在WinForm开发中必不可少。
本文介绍在WinForm开发中如何使用多线程,以及在线程中如何通过Control.Invoke方法返回窗体主线程执行相关操作。
-. WinForm多线程编程
1. new Thread()
新开一个线程,执行一个方法,没有参数传递:
private void DoWork() {
Thread t = new Thread(new ThreadStart(this.DoSomething));
t.Start();
}
private void DoSomething() {
MessageBox.Show("thread start");
}新开一个线程,执行一个方法,并传递参数:
private void DoWork() {
Thread t = new Thread(new ParameterizedThreadStart(this.DoSomething));
t.Start("guozhijian");
}
private void DoSomething(object o) {
MessageBox.Show(o.ToString());
}参数定义为object类型。
2. ThreadPool
众所周知,新开一个线程代价是很高昂的,如果我们每个操作都新开一个线程,那么太浪费了,于是,下面使用线程池。
无参数传递:
private void DoWork() {
ThreadPool.QueueUserWorkItem(new WaitCallback(this.DoSomething));
}
private void DoSomething(object o) {
MessageBox.Show("thread start");
}有参数传递:
private void DoWork() {
ThreadPool.QueueUserWorkItem(new WaitCallback(this.DoSomething), "guozhijian");
}
private void DoSomething(object o) {
MessageBox.Show(o.ToString());
}使用匿名方法更灵活:
private void DoWork() {
string name = "guozhijian";
ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object o){
MessageBox.Show(name);
}));
}在匿名代码段里面可以直接访问局部变量,不用在关心参数传递的问题
二. Invoke
1. this.Invoke
现在,在业务线程里面执行完毕,要改变窗体控件的值了,此时,如果直接通过this得到控件的句柄,然后对它进行操作是会抛异常的,.Net WinForm Application里面是不允许这样的操作的。这是,可以调用Invoke方法
2.Invoke方法签名:
object Control.Invoke(Delegate Method)
object Control.Invoke(Delegate Method, params object[] args)
3.使用自定义委托
private void DoWork() {
WaitCallback wc = new WaitCallback(this.DoSomething);
ThreadPool.QueueUserWorkItem(wc, "Guozhijian");
}
private delegate void MyInvokeDelegate(string name);
private void DoSomething(object o) {
this.Invoke(new MyInvokeDelegate(this.ChangeText), o.ToString());
}
private void ChangeText(string name) {
this.textBox1.Text = name;
}哦,太麻烦了,难道我每次都要定义一个委托啊,这样可不行。
4.使用System.Action:
private void DoWork() {
WaitCallback wc = new WaitCallback(this.DoSomething);
ThreadPool.QueueUserWorkItem(wc, "Guozhijian");
}
private void DoSomething(object o) {
this.Invoke(new Action<string>(this.ChangeText), o.ToString());
}
private void ChangeText(string name) {
this.textBox1.Text = name;
}本例传递一个参数,System.Action有很多个重载,可以无参数(非泛型),而最多可以有四个参数,同样采用匿名方法,不使用泛型形式的System.Action,如下:
private void DoWork() {
WaitCallback wc = new WaitCallback(this.DoSomething);
ThreadPool.QueueUserWorkItem(wc, "Guozhijian");
}
private void DoSomething(object o) {
this.Invoke(new Action(delegate() {
this.textBox1.Text = o.ToString();
}));
}5.使用System.Func
如果Invoke调用主窗体操作之后,还希望在调用完得到一个返回值:
private void DoWork() {
WaitCallback wc = new WaitCallback(this.DoSomething);
ThreadPool.QueueUserWorkItem(wc, "Guozhijian");
}
private void DoSomething(object o) {
System.Func<string, int> f = new Func<string, int>(this.GetId);
object result = this.Invoke(f,o.ToString());
MessageBox.Show(result.ToString());
}
private int GetId(string name) {
this.textBox1.Text = name;
if (name == "Guozhijian") {
return 999;
}
else {
return 0;
}
}result的值为 999。
System.Func同样有很多泛形重载,这里不赘述。
6.关于Invoke的拥有者:Control
本文例中都是用this来引用,这里this替换为窗体任何一个控件的句柄都是OK的,因为Control.Invoke含义是将方法委托给拥有该Control的线程去执行。
C#多线程编程总结的更多相关文章
- Web Worker javascript多线程编程(一)
什么是Web Worker? web worker 是运行在后台的 JavaScript,不占用浏览器自身线程,独立于其他脚本,可以提高应用的总体性能,并且提升用户体验. 一般来说Javascript ...
- Web Worker javascript多线程编程(二)
Web Worker javascript多线程编程(一)中提到有两种Web Worker:专用线程dedicated web worker,以及共享线程shared web worker.不过主要讲 ...
- windows多线程编程实现 简单(1)
内容:实现win32下的最基本多线程编程 使用函数: #CreateThread# 创建线程 HANDLE WINAPI CreateThread( LPSECURITY_ATTRIBUTES lpT ...
- Rust语言的多线程编程
我写这篇短文的时候,正值Rust1.0发布不久,严格来说这是一门兼具C语言的执行效率和Java的开发效率的强大语言,它的所有权机制竟然让你无法写出线程不安全的代码,它是一门可以用来写操作系统的系统级语 ...
- windows多线程编程星球(一)
以前在学校的时候,多线程这一部分是属于那种充满好奇但是又感觉很难掌握的部分.原因嘛我觉得是这玩意儿和编程语言无关,主要和操作系统的有关,所以这部分内容主要出现在讲原理的操作系统书的某一章,看完原理是懂 ...
- Java多线程编程核心技术---学习分享
继承Thread类实现多线程 public class MyThread extends Thread { @Override public void run() { super.run(); Sys ...
- python多线程编程
Python多线程编程中常用方法: 1.join()方法:如果一个线程或者在函数执行的过程中调用另一个线程,并且希望待其完成操作后才能执行,那么在调用线程的时就可以使用被调线程的join方法join( ...
- 浅述WinForm多线程编程与Control.Invoke的应用
VS2008.C#3.0在WinForm开发中,我们通常不希望当窗体上点了某个按钮执行某个业务的时候,窗体就被卡死了,直到该业务执行完毕后才缓过来.一个最直接的方法便是使用多线程.多线程编程的方式在W ...
- Java—多线程编程
一个多线程程序包含两个或多个能并发运行的部分.程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径. 进程:一个进程包括由操作系统分配的内存空间,包含一个或多个线程.一个线程不能独立的存 ...
- [转]Linux 的多线程编程的高效开发经验
Linux 平台上的多线程程序开发相对应其他平台(比如 Windows)的多线程 API 有一些细微和隐晦的差别.不注意这些 Linux 上的一些开发陷阱,常常会导致程序问题不穷,死锁不断.本文中我们 ...
随机推荐
- 20151130test->20160530
过了6个月了,有些长进么?哈 go go go 开源镜像 http://mirrors.163.com/
- ABAP 内表的行列转换-发货通知单-打印到Excel里
需要传入数据到Excel里的模板如上图所示 ********************** * 设计主要逻辑与原理说明 ...
- C# 操作IIS方法集合
如果在win8,win7情况下报错:未知错误(0x80005000) 见http://blog.csdn.net/ts1030746080/article/details/8741399 using ...
- SuperIndicator 专做轮播图库,没有之一,支持轮播图无限循环
github地址:https://github.com/hejunlin2013/SuperIndicator SuperIndicator a superindicatorlibray for vi ...
- 【leetcode】 Permutation Sequence (middle)
The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all of the p ...
- 【leetcode】Same Tree(easy)
Given two binary trees, write a function to check if they are equal or not. Two binary trees are con ...
- 【编程题目】输入两个整数 n 和 m,从数列 1,2,3.......n 中 随意取几个数, 使其和等于 m ... ★
第 21 题(数组)2010 年中兴面试题编程求解:输入两个整数 n 和 m,从数列 1,2,3.......n 中 随意取几个数,使其和等于 m ,要求将其中所有的可能组合列出来. 我的思路: 从小 ...
- Struts2拦截器之FileUploadInterceptor
一.它能做什么? 借助于这个拦截器我们可以实现文件的上传和下载功能. 理论部分: struts2的文件上传下载功能也要依赖于Apache commons-fileupload和Apache commo ...
- NYOJ题目1045看美女
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAskAAAK5CAIAAADCdSR7AAAgAElEQVR4nO3dP3Lbuv434HcT7r2Q1F
- NYOJ题目889求距离
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAsYAAAJ2CAIAAADTwNOXAAAgAElEQVR4nO3dPVLrSteG4W8S5B4IsQ