分类:
C#
创建一个控制台应用程序,代码如下:
using System; using System.Threading; namespace ConsoleApplication1 { public delegate string AsyncDelegate(int callDuration, out int threadId); class Program { static void Main(string[] args) { //Fun1(); //Fun2(); //Fun3(); Fun4(); Console.ReadLine(); } private static int threadId; //阻塞等待 使用 EndInvoke 等待异步调用 static void Fun1() { //创建示例类的实例。 AsyncDemo ad = new AsyncDemo(); // 创建委托 AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod); // 委托在这里开始异步调用。 IAsyncResult ar = dlgt.BeginInvoke(5000,out threadId, null, null); //人为的线程阻塞。 Thread.Sleep(0); //Thread.CurrentThread.Name = "主线程"; Console.WriteLine("主线程 {0}开始工作",Thread.CurrentThread.ManagedThreadId); // 委托开始EndInvoke调用,这个过程会使主线程等待异步调用完成并返回结果。 string ret = dlgt.EndInvoke(out threadId, ar); Console.WriteLine("使用 EndInvoke 等待异步调用!!!"); Console.WriteLine("异步线程 {0},返回值 \"{1}\".", threadId, ret); Console.WriteLine("主线程{0}结束工作", Thread.CurrentThread.ManagedThreadId); } //阻塞等待 使用 WaitHandle 等待异步调用 static void Fun2() { AsyncDemo ad = new AsyncDemo(); AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod); IAsyncResult ar = dlgt.BeginInvoke(5000,out threadId, null, null); Thread.Sleep(0); Console.WriteLine("主线程 {0}开始工作", Thread.CurrentThread.ManagedThreadId); //主线程在这里等待,直到异步线程执行完。 ar.AsyncWaitHandle.WaitOne(); // 和前一方案的区别在于,你可以在异步调用完成后,获取异步调用返回值之前 //在这里做点任何你想作的事。 //调用EndInvoke获取异步调用的返回结果. string ret = dlgt.EndInvoke(out threadId, ar); Console.WriteLine("使用 WaitHandle 等待异步调用!!!"); Console.WriteLine("异步线程 {0},返回值 \"{1}\".", threadId, ret); Console.WriteLine("主线程{0}结束工作", Thread.CurrentThread.ManagedThreadId); } //轮询状态 轮询异步调用完成 static void Fun3() { AsyncDemo ad = new AsyncDemo(); AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod); IAsyncResult ar = dlgt.BeginInvoke(5000,out threadId, null, null); Console.WriteLine("使用轮询异步调用!!!"); Console.WriteLine("主线程 {0}开始工作", Thread.CurrentThread.ManagedThreadId); //这里每隔10毫秒就检测(轮询)一下异步执行的状态, //直到异步调用完成,IsCompleted的值变为ture为止。 int count = 0; DateTime a = DateTime.Now; while (ar.IsCompleted == false) { Thread.Sleep(10); count++; } string dt = (DateTime.Now - a).ToString(); Console.WriteLine(count); Console.WriteLine("程序耗时"+dt); //还记得微软的那个善意的提醒吗?虽然IsCompleted为true了, //我们还是调用一下EndInvoke,来获取返回值。 string ret = dlgt.EndInvoke(out threadId, ar); Console.WriteLine("异步线程 {0},返回值 \"{1}\".", threadId, ret); Console.WriteLine("主线程{0}结束工作", Thread.CurrentThread.ManagedThreadId); } //通知机制 异步调用完成时执行回调方法 static void Fun4() { AsyncDemo ad = new AsyncDemo(); AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod); //注意第三个参数,这就是我们要用到的回调方法。 //第四个参数更为有趣,它可以是任何Object对象,这里它就是 //执行异步调用的委托本身,把委托本身传递进去的原因在下面可以看到。 Console.WriteLine("异步调用完成时执行回调!!!"); Console.WriteLine("主线程 {0}开始工作", Thread.CurrentThread.ManagedThreadId); IAsyncResult ar = dlgt.BeginInvoke(5000,out threadId, new AsyncCallback(CallbackMethod), dlgt); Console.WriteLine("主线程 {0}结束工作", Thread.CurrentThread.ManagedThreadId); Console.ReadLine(); } //回调函数必须严格的遵照AsyncCallback委托的签名。 static void CallbackMethod(IAsyncResult ar) { //在这里,上面那个dlgt作为参数的作用得到了体现,原来它就是为了完成对EndInvoke的调用啊。 AsyncDelegate dlgt = (AsyncDelegate)ar.AsyncState; //通过对EndInvoke的调用获取返回值。 string ret = dlgt.EndInvoke(out threadId, ar); Console.WriteLine("异步线程 {0},返回值 \"{1}\".", threadId, ret); } } //使用异步编程模型 public class AsyncDemo { public string TestMethod(int callDuration, out int threadId) { Console.WriteLine("异步方法开始工作"); Thread.Sleep(callDuration); //Thread.CurrentThread.Name = "异步线程"; threadId = Thread.CurrentThread.ManagedThreadId; return "异步方法执行时间 " + callDuration.ToString(); } } }
代码比较简单了,看不懂 多调休跑几遍就懂了!
评价
排名
6
文章
6
粉丝
16
评论
8
{{item.articleTitle}}
{{item.blogName}} : {{item.content}}
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2024TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术