.Net 开发环境下对异步三种模式的了解

小编记得在面试的时候被问到最多的一个问题是:你对异步有什么认识?经常会第一时间想到多线程,BeginInvoke等,但是在.net中是有对异步模式有区分的,本篇文章是小编自己对于异步模式的一个知识梳理,不喜勿喷哈,欢迎各位大神指导。

总的来说,多线程只是异步的一种实现方式,异步模式在.net历史长河中主要演变了三种模式:APM=>EAP=>TAP,下面咱们就一步步的介绍这三世同堂

APM:

APM 是.net1.0的时候诞生的,属于爷爷辈,它的异步操作是基于委托,主要特征是使用了IAsyncResult接口,IAsyncResult主要还是针对异步状态的获取或者结果的接收,BegainInvoke是异步方法的执行,EndInvoke是异步方法结果返回等待,这里要注意的是回调函数可以为空,意思是不需要回调函数也可以。

 class APMTest
    {
        private delegate string DelegateMethodHandle(); //APM 异步是基于委托的
        public static void Test()
        {
            DelegateMethodHandle delegateMethodHandle = new DelegateMethodHandle(new APMTest().TestMethodAsync);
            IAsyncResult asyncResult = delegateMethodHandle.BeginInvoke(new APMTest().CallBackMethod, null);
            Console.WriteLine("异步已经执行,这里继续做主线程的工作");          
            Console.WriteLine(delegateMethodHandle.EndInvoke(asyncResult));
            Console.WriteLine("EndInvoke会阻塞当前主线程,这里将在异步操作执行完后执行");
            Console.ReadKey();
        }
        
        private string TestMethodAsync()
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(string.Format("这里讲执行异步方法{0}", i.ToString()));
            }
            return "执行异步方法完毕";
        }

        private void CallBackMethod(IAsyncResult ar)
        {            
            Console.WriteLine("这里是异步执行完回调方法");
            
        }
    }

EAP:

EAP是.net2.0的时候诞生的,属于爸爸辈,它的异步操作是基于事件,可以说是在APM上的一种延续更新,事件也是基于委托的,一般回调事件注册结尾命名为XXXCompleted,异步执行方法结尾命名为XXXAsync,回调函数在这里有一个明显的变化,由APM的回调函数作为参数传入变为回调事件的注册,而异步方法的结果也作为DownloadStringCompletedEventArgs 数据的一部分传入。

 class EAPTest
    {
        public static void Test()
          {
            WebClient webClient = new WebClient();
            webClient.DownloadStringCompleted += DownloadStringCompleted;//回调事件
            webClient.DownloadStringAsync(new Uri("http://www.baidu.com"));
            Console.ReadKey();
         }
 
         private static void DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
         {
             Console.WriteLine("这里异步请求网页完毕后执行:" + e.Result);
         }


    }

TAP:

TAP是.net4.0的时候诞生的,属于儿子辈,也是目前.net比较推崇使用的,他的异步操作正确来说是基于Task对象,这里面有比较多的属性和方法让我们更好的管理异步,例如CancellationToken令牌对象里面就封装了对Task的取消等操作。在线程基础面上,Thread或ThreadPool是前台线程的,而Task是属于后台线程,所以有几个要注意的,1.在Task 中尽量不要使用Thread.Sleep,应该使用Task.Delay,并且Delay 也可以传入令牌取消延时。2。可以多使用async/await,async 声明异步方法,await接收异步返回值,.net 在4.5后推出的TPL模型,也可以多多使用 ,属于对Task的进一步提升

 class TAPTest
    {
        public static void Test()
        {
            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
            Task task = new Task(()=> new TAPTest().TestMethodAsync(cancellationTokenSource.Token));
            task.Start();
            Console.WriteLine("异步已经执行,这里继续做主线程的工作");            
            cancellationTokenSource.Cancel(); //取消当前任务
            Console.WriteLine(task.GetAwaiter().GetResult());
            Console.WriteLine("GetAwaiter会阻塞当前线程等待返回值");
            Console.ReadKey();

        }

        private string TestMethodAsync(CancellationToken cancellationToken)
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(string.Format("这里讲执行异步方法{0}", i.ToString()));
                if(cancellationToken.IsCancellationRequested)
                {
                    break;
                }
            }
            return "执行异步方法完毕";
        }
       
    }

你可能感兴趣的:(面试,职场和发展,c#,.net)