线程学习1——异步委托
2011-05-30 14:59
190 查看
一.为什么使用线程
简单来讲,就是用线程来实现,在程序运行过程中,还可以同时执行其他操作。
二.线程的概述
线程是程序中独立的指令流。使用C#编写任何程序时,都有一个入口:Main()方法。程序从Main()方法的第一条语句开始执行,直到这个方法返回为止。
在.net framework class library中,所有与多线程机制应用相关的类都是放在System.Threading命名空间中的。
如果你想在你的应用程序中使用多线程,就必须包含这个类。
三.异步委托
创建线程的一个简单方式是定义一个委托,异步调用它。
那什么是异步委托呢?异步委托就是定义一个方法,开一个新线程,让这个方法在后台执行。
委托是方法的类型安全引用。Delegate类支持异步调用的方法,在后台Delegate类会创建一个执行任务的线程。
第一步:定义方法和委托
我们先定义一个需要一定时间才能完成的方法:TakesTime(int data,int ms),这个方法调用Thread.Sleep方法,至少需要经过传入的参数ms毫秒后才能执行完。
要在委托中调用这个方法,必须定义一个有相同参数和返回类型的委托:
第二步:等待委托的结果的方式
第一种方式——投票(检测委托,即反复询问)
将方法交给后台执行后,我们仍可以检查委托的一些执行状态,如下面所示的是否完成(IsComplated)。
所创建的Delegate类提供了BeginInvoke()方法,在该方法中,可以传递用委托类型定义的输入参数。BeginInvoke()方法总是有两个AsyncCalllback和Object类型的额外参数。
其返回类型为
IAsyncResult。通过这个返回结果可以获得该委托的相关信息。下面是用了IsComplated方法检查委托是否完成,只要委托没有完成程序将一直执行:
运行程序时,委托线程和主线程同时运行,委托线程完毕后,主线程的循环就停止了。同时也可以在主线程中调用EndInvoke方法结束后台线程。
如果后台线程没有完成,EndInvoke方法会一直等待,直到后台线程完成或者主线程结束。
第二种方式——等待句柄(等待一段时间后在询问)
等待异步委托的结果的另一种方法就是使用IAsyncReault相关联的等待句柄。使用AsyncWaitHandle属性就可以访问等待句柄。这个属性返回WaitHandle类型的对象,
它可以等待委托线程完成其任务。WaitOne()方法将一个超时时间作为可选的第一个参数,在其中可以定义要等待的最长时间。如果发生超时WaitOne方法就返回false。
第三种方式——异步回调
异步回调是指:将任务委托给后台一个线程,这个任务结束后,自动调用一个已定义的方法,而不需要在主线程中等待结果。
在BeginInvoke()方法的第三个参数中,可以传递一个满足IAsyncCallback委托需要的方法。在该委托方法执行完之后,后台线程会调用这个方法,二不需要在主线程中等待后台线程的结果。
IAsyncCallback委托定义了一个IAsyncResult类型的参数,其返回类型为void。以下的代码中,我们先定义一个TakesTimeComplated()方法,用作回调方法。
之后我们在主线程中启动这个方法:
简单来讲,就是用线程来实现,在程序运行过程中,还可以同时执行其他操作。
二.线程的概述
线程是程序中独立的指令流。使用C#编写任何程序时,都有一个入口:Main()方法。程序从Main()方法的第一条语句开始执行,直到这个方法返回为止。
在.net framework class library中,所有与多线程机制应用相关的类都是放在System.Threading命名空间中的。
如果你想在你的应用程序中使用多线程,就必须包含这个类。
三.异步委托
创建线程的一个简单方式是定义一个委托,异步调用它。
那什么是异步委托呢?异步委托就是定义一个方法,开一个新线程,让这个方法在后台执行。
委托是方法的类型安全引用。Delegate类支持异步调用的方法,在后台Delegate类会创建一个执行任务的线程。
第一步:定义方法和委托
我们先定义一个需要一定时间才能完成的方法:TakesTime(int data,int ms),这个方法调用Thread.Sleep方法,至少需要经过传入的参数ms毫秒后才能执行完。
public static int TakesTime(int data, int ms) { Console.WriteLine("TakesTime started"); Thread.Sleep(ms); Console.WriteLine("\nTakesTime complated"); return ++data; }
要在委托中调用这个方法,必须定义一个有相同参数和返回类型的委托:
public delegate int TakesTimeDelegate(int data, int ms);
第二步:等待委托的结果的方式
第一种方式——投票(检测委托,即反复询问)
将方法交给后台执行后,我们仍可以检查委托的一些执行状态,如下面所示的是否完成(IsComplated)。
所创建的Delegate类提供了BeginInvoke()方法,在该方法中,可以传递用委托类型定义的输入参数。BeginInvoke()方法总是有两个AsyncCalllback和Object类型的额外参数。
其返回类型为
IAsyncResult。通过这个返回结果可以获得该委托的相关信息。下面是用了IsComplated方法检查委托是否完成,只要委托没有完成程序将一直执行:
static void Main(string[] args) { TakesTimeDelegate mTakesTime = TakesTime; //将任务交给后台执行 IAsyncResult mIAsyncResult = mTakesTime.BeginInvoke(1, 9000, null, null); //等待后台线程结束 while (!mIAsyncResult.IsCompleted) { Console.Write("."); Thread.Sleep(50); } int result = mTakesTime.EndInvoke(mIAsyncResult); //获取返回结果 Console.WriteLine("Result:{0}", result); Console.ReadLine(); }
运行程序时,委托线程和主线程同时运行,委托线程完毕后,主线程的循环就停止了。同时也可以在主线程中调用EndInvoke方法结束后台线程。
如果后台线程没有完成,EndInvoke方法会一直等待,直到后台线程完成或者主线程结束。
第二种方式——等待句柄(等待一段时间后在询问)
等待异步委托的结果的另一种方法就是使用IAsyncReault相关联的等待句柄。使用AsyncWaitHandle属性就可以访问等待句柄。这个属性返回WaitHandle类型的对象,
它可以等待委托线程完成其任务。WaitOne()方法将一个超时时间作为可选的第一个参数,在其中可以定义要等待的最长时间。如果发生超时WaitOne方法就返回false。
static void Main(string[] args) { TakesTimeDelegate mTakesTime = TakesTime; IAsyncResult mIAsyncResult = mTakesTime.BeginInvoke(1, 3000, null, null); while (true) { Console.Write("."); if (mIAsyncResult.AsyncWaitHandle.WaitOne(50, false)) { Console.WriteLine("Can get the result now"); break; } } int result = mTakesTime.EndInvoke(mIAsyncResult); Console.WriteLine("Reault: {0}", result); Console.ReadLine(); }
第三种方式——异步回调
异步回调是指:将任务委托给后台一个线程,这个任务结束后,自动调用一个已定义的方法,而不需要在主线程中等待结果。
在BeginInvoke()方法的第三个参数中,可以传递一个满足IAsyncCallback委托需要的方法。在该委托方法执行完之后,后台线程会调用这个方法,二不需要在主线程中等待后台线程的结果。
IAsyncCallback委托定义了一个IAsyncResult类型的参数,其返回类型为void。以下的代码中,我们先定义一个TakesTimeComplated()方法,用作回调方法。
public static void TakesTimeComplated(IAsyncResult ar) { if (ar == null) { throw new ArgumentNullException("ar"); } TakesTimeDelegate t3 = ar.AsyncState as TakesTimeDelegate; Trace.Assert(t3 != null, "对象类型不对"); int result = t3.EndInvoke(ar); Console.WriteLine("result {0}", result); }
之后我们在主线程中启动这个方法:
static void Main(string[] args) { TakesTimeDelegate t3 = TakesTime; t3.BeginInvoke(1, 3000, TakesTimeComplated, t3); for (int i = 0; i < 100; i++) { Console.Write("."); Thread.Sleep(50); } Console.ReadLine(); }
相关文章推荐
- 今日学习:关于C#多线程之一——异步委托
- 黑马程序员_学习日记65_713ASP.NET(委托、托管、扩展方法、泛型委托、进程_应用程序域_线程、多线程、异步委托)
- 线程学习1——异步委托
- 委托,线程,同步,异步的学习(一)
- C# 线程的异步,委托,回调
- [深入学习C#]完成异步委托的三种方式
- 通过代码学习C#&.NET——委托使用(线程、任务)
- 线程的初步学习(委托的初步使用)
- C# 创建线程的简单方式:异步委托 .
- C# :线程中操作多控件 (委托实现异步及同步的方法)
- Unity之C#——异步委托开启线程,三种方法检测结束
- 委托之异步学习(转载)
- Linux程序设计学习笔记----异步信号与线程属性控制
- 谈.Net委托与线程——创建无阻塞的异步调用
- C#中的线程一(委托中的异步)
- Android开发学习笔记十四 异步线程之AsyncTask
- C#中的线程一(委托中的异步)
- c#利用委托进行异步跨线程加载到窗体数据
- (二)线程--通过委托异步调用方法
- 谈.Net委托与线程——创建无阻塞的异步调用