tnblog
首页
登录

异步线程,轮询的demo

196人阅读 2018/12/19 14:35 评论:0 手机 收藏 关注
分类: C#

        创建一个控制台应用程序,代码如下:

  1. 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();
    }
    }
    }

        代码比较简单了,看不懂 多调休跑几遍就懂了!

评价
Decorating heart
文章
6
粉丝
16
评论
8
分类
16
{{item.ArticleTitle}}
{{item.BlogName}} : {{item.Content}}