分享一个异步线程,轮询的demo

//创建一个控制台应用程序如下:
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();
        }
    }

}

上面的注释都很详细相信大家很容易看得懂。

为博主转载,忘记此demo的出处了,如若侵权,即可删除。

你可能感兴趣的:(C#)