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(1000,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(1000,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开头的方法来处理结果,这两个方法可以运行在不同的线程,这样就可以实现异步编程了。

原文地址:https://www.cnblogs.com/tracine0513/p/3405889.html