c#线程的几种启动方法
一 启动普通线程
ThreadStart与ParameterizedThreadStart建立新线程
优缺点:简单,但难于管理,线程过多会影响系统的性能。
二 启动CLR线程池的工作者线程(普通线程和线程池线程可以通过Thread.CurrentThread.IsThreadPoolThread区别)
1、ThreadPool.QueueUserWorkItem(WaitCallback)(Object默认为null)和 ThreadPool.QueueUserWorkItem(WaitCallback,Object)
这两个静态方法可以直接启动工作者线程 ,其中WaitCallback委托指向一个带有Object参数的无返回值方法。
举例:
public void Method(object o){ } //带object参数无返回值的方法
ThreadPool.QueueUserWorkItem(new WaitCallback(Method));
优缺点:简单方便,但委托指向的必须是一个带有Object参数的无返回值方法,不适用带多个参数及返回值的方法。
2、委托类(常用)
BeginInvoke异步调用方法,EndInvoke方法来获得返回值
举例:
private int Method(int ms){//要异步执行的方法}
private delegate int TaskDelegate(int ms);//申明委托
TaskDelegate task = new TaskDelegate(Method);//建立委托,并指向要执行的方法
IAsyncResult iar = task.BeginInvoke(,null,null);//异步调用委托,传入方法参数ms
While(!task.IsCompleted)//通过轮询方式,判断异步操作是否完成,好让主线程执行另外工作
{//否则直到异步线程完成前主线程将一直处于阻塞状态,影响执行效率
......//主线程执行代码
}
int result = task.EndInvoke(iar); //获取返回值
优缺点://使用BeginInvoke、EndInvoke方法简单方便,但是如果异步调用未完成EndInvoke将一直阻塞到其完成,因此主线程不能从事其他工作。虽然可以通过轮询方式来检测异步方法的状态让主线程工作,但非常麻烦而且效率不高。
3、回调函数
使用AsyncCallback就可以绑定一个方法作为回调函数,在回调函数中执行EndInvoke。回调函数必须是带参数IAsyncResult且无返回值的方法:void AsycnCallbackMethod(IAsyncResult result)
private delegate int TaskDelegate(int ms);//申明委托
private int Method(int ms)
{
//要异步执行的方法
}
TaskDelegate task = new TaskDelegate(Method);//建立委托,并指向要执行的方法
IAsyncResult sync = task.BeginInvoke(,new AsyncCallback(ACMethod), null);
//异步调用委托,并绑定ACMethod方法作为回调函数,这样主线程就可以继续工作不用等待了
private void ACMethod(IAsyncResult iar) //回调函数
{
AsyncResult ar = iar as AsyncResult;//类型装转换,接口IAsyncResult没有AsyncDelegate属性,但AsyncResult有
TaskDelegate task = ar.AsyncDelegate as TaskDelegate;
//因为EndInvoke需要两个参数:委托实例task和AsyncResult实例ar
int result = task.EndInvoke(ar);//获取委托方法Method的返回值
}
关于线程异步编程:委托delegate、BeginInvoke, EndInvoke, IAsycResult(监控异步,可以通过IsConpleted进行判断异步调用是否完成),AsyncCallBack委托,AsyncState 实例( 在回调函数中通过IAsyncResult.AsyncState来强制转换)。了解这些,基本就理解异步编程的真谛了。异步操作通常用于执行完成时间可能较长的任务, 如打开大文件、连接远程计算机或查询数据库。但应注意, 滥用异步, 会影响性能, 而且增加编程难度, 故应慎重考虑。
AsyncCallBack:异步回调函数的委托,引用在异步操作完成时调用的方法。
IAsyncResult:具有AsyncState属性,获取BeginInvoke方法的最后一个参数object,是启动异步操作的方法(即BeginInvoke)的返回类型(接口),当异步操作完成时,IAsyncResult对象也将传递给由AsyncCallback委托调用的方法(即回调函数的参数 )。
AsyncResult:具有AsyncDelegate属性和AsyncState属性,AsyncDelegate该属性保存在其上调用异步调用的委托对象。AsyncState属性可以获取BeginInvoke(AsyncCallback,object)的最后一个参数object。所以也可以将委托对象作为BeginInvoke最后一个参数,这样可以在回调函数中通过AsyncState获取委托对象
BeginInvoke、EndInvoke:在.net中通常以BeginXXXX开头的方法完成启动,以End开头的方法来处理结果,这两个方法可以运行在不同的线程,这样就可以实现异步编程了。
c#线程的几种启动方法的更多相关文章
- angular2系列教程(十)两种启动方法、两个路由服务、引用类型和单例模式的妙用
今天我们要讲的是ng2的路由系统. 例子
- Service的两种启动方法
刚才看到一个ppt,介绍service的两种启动方法以及两者之间的区别. startService 和 bindService startService被形容为我行我素,而bindService被形容 ...
- mongodb的几种启动方法
1 mongodb的几种启动方法 启动Mongodb服务有两种方式,前台启动或者Daemon方式启动,前者启动会需要保持当前Session不能被关闭,后者可以作为系统的fork进程执行,下文中的p ...
- Java线程的三种实现方法
Java多线程详解 线程简介 多任务,多线程 多任务情况中,虽然可以完成,但是实际上,多任务的完成是由一个一个小任务的完成来实现的,也就是说在执行多任务时,不是同时执行多个任务,而是一个时间段内只完成 ...
- Android 线程 thread 两种实现方法
原文链接: http://blog.csdn.net/boyupeng/article/details/6208072 这篇文章中有三点需要提前说明一下, 一: 在android中有两种实现线程thr ...
- Android—— 线程 thread 两种实现方法!(转)
原文地址:http://blog.csdn.net/boyupeng/article/details/6208072 这篇文章中有三点需要提前说明一下, 一: 在android中有两种实现线程thre ...
- 【转载】JAVA中线程的两种实现方法-实现Runnable接口和继承Thread类
转自: http://blog.csdn.net/sunguangran/article/details/6069317 非常感谢原作者,整理的这么详细. 在java中可有两种方式实现多线程,一种是继 ...
- Task用法(1)-启动方法
第一.基本使用 Thread,ThreadPool,Task的区别 Task是.NET4.0加入的,跟线程池ThreadPool的功能类似,用Task开启新任务时,会从线程池中调用线程,而Thread ...
- Android(java)学习笔记227:服务(service)之服务的生命周期 与 两种启动服务的区别
1.之前我们在Android(java)学习笔记171:Service生命周期 (2015-08-18 10:56)说明过,可以回头看看: 2.Service 的两种启动方法和区别: (1)Servi ...
随机推荐
- Android学习路线(十一)管理Activity的生命周期
当一个用户进入.退出,再次进入你的应用时,你的应用中的Activity 会在它的生命周期的各个状态下切换. 比如,当你的activity第一次启动.它出如今系统的前方接受用户的焦点.在这个过程中,An ...
- hdu4758 Walk Through Squares 自动机+DP
题意:给n*m的地图,在地图的点上走,(n+1)*(m+1)个点,两种操作:往下走D和往右走R.现在要从左上角走到右下角,给定两个操作串,问包含这两个串的走法总共有多少种. 做法:用这两个串构建自动机 ...
- Ubuntu中全然卸载Nginx
Nginx尽管好用,可是一旦关键配置文件被改动,想要卸载重装却是相当困难.本人由于採用apt-get方式安装后又源代码安装了Nginx,结果出现冲突,卸载不了,安装不上,非常是蛋疼.基本的问题还是Ng ...
- Android pm命令用法
Sam综观有关PackageManager时,无意中发现Android 下提供一个pm命令,通常放在/system/bin/下. 这个命令与Package有关.且很有用.所以研究之. 0. Usage ...
- Linux了解进程的地址空间
供Linux了解虚拟内存,非常好的引导了.原文链接:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=26683523&i ...
- poj2431 Expedition
直接代码... #include<string.h> #include<stdio.h> #include<queue> #include<iostream& ...
- (两)unity4.6Ugui中国教程文档-------总结-UGUI Canvas
大家好,我是广东太阳. 转载请注明出处:http://write.blog.csdn.net/postedit/38922399 更全的内容请看我的游戏蛮牛地址:http://www.unitym ...
- ACdreamoj(1105)模拟题
题意:射一次激光最多能够攻击到几个敌人(因为激光非常强大,能够在击中敌人后穿过它,而瑶瑶自己的坦克因为有特殊装置,所以不会被激光击中.激光也会直接穿过它) . 表示此处为空地 * 表示此处为障碍(激光 ...
- 小记 js unicode 编码解析
原文:小记 js unicode 编码解析 var str = "\\u6211\\u662Funicode\\u7F16\\u7801"; 关于这样的数据转换为中文问题,常用的两 ...
- oracle_powerdesinger逆向工程 , PDM 文件 注释到name的完美解决方案 comment2name
1. 从oracle 到 PDM文件 逆向工程中 ,需要注意 去掉“” ,这个百度下很多帖子,用于去掉引号 2. 从注释copy到name运行脚本会有个问题就是 ,有些注释太长,不美观 解决方案, ...