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 ...
随机推荐
- java反思reflect 分析Object物
直接看它的一个例子 </pre><pre name="code" class="java">package reflect; impor ...
- (大数据工程师学习路径)第三步 Git Community Book----高级技能
一.创建新的空分支 1.创建新的空分支 在偶尔的情况下,你可能会想要保留那些与你的代码没有共同祖先的分支.例如在这些分支上保留生成的文档或者其他一些东西.如果你需要创建一个不使用当前代码库作为父提交的 ...
- 每天收获一点点------Hadoop之HDFS基础入门
一.HDFS出现的背景 随着社会的进步,需要处理数据量越来越多,在一个操作系统管辖的范围存不下了,那么就分配到更多的操作系统管理的磁盘中,但是却不方便管理和维护—>因此,迫切需要一种系统来管理多 ...
- mysql及powerdesigner的初次使用
原文:mysql及powerdesigner的初次使用 MYSQL的下载与安装: 下载与安装指导教程: http://jingyan.baidu.com/article/597035521d5de28 ...
- Is it always safe to call getClass() within the subclass constructor?(转)
14down votefavorite An article on classloading states that the method getClass() should not be cal ...
- 从头到尾彻底理解KMP(转)
引言 KMP原文最初写于2年多前的2011年12月,因当时初次接触KMP,思路混乱导致写也写得非常混乱,如此,留言也是骂声一片.所以一直想找机会重新写下KMP,但苦于一直以来对KMP的理解始终不够,故 ...
- mysql 在创建批处理脚本日志表信息
mysql在批处理脚本通过存储过程如下所示创建日志信息表: drop PROCEDURE if EXISTS reqSp; DELIMITER // create procedure reqSp(sT ...
- Android使用surface直接显示yuv数据(三)
在本文中,Java创建UI和关节JNI经营层surface直接显示yuv数据(yv12).发展环境Android 4.4,驰A23平台. package com.example.myyuvviewer ...
- sqlplus登录问题
问题1.sqlplus login -- SP2-0750: You may need to set ORACLE_HOME to your Oracle software directory 在/e ...
- 运行时间(Java版本)—转换毫秒到时分秒日期
第一种方式: import java.util.Calendar; import java.util.TimeZone; public class Test { /** * 将毫秒转换为年月日时分秒 ...