C#笔记(.Net异步编程async/await)3

C#笔记(.Net异步编程async/await)3

最近学习了.Net下异步编程,因此有必要总结下,以后可以参考

首先我们来了解下.net下多线程的方法

关于多线程,早在.NET2.0时代,基础类库中就提供了Thread实现,.Net4.0时代推出了新的多线程模型Task.那让我们来看下两者的区别吧。

#region 多线程测试
        private static void TestThread()
        {
            Console.WriteLine("多线程测试");
            for (int i = 0; i < 50; i++)
            {
                new Thread(dorun1).Start();//多线程模式
            }

            for (int j = 0; j < 50; j++)
            {
                Task.Run(() => { dorun2(); });
            }
        }

        private static void dorun1()
        {
            Console.WriteLine("Thread线程编号为:" + Thread.CurrentThread.ManagedThreadId);
        }

        private static void dorun2()
        {
            Console.WriteLine("Task线程编号为:" + Thread.CurrentThread.ManagedThreadId);
        }
        #endregion

通过此测试代码,我们可以发现Thread显示的线程编号都是唯一的,因为每次都会创建一个新的线程来操作,但是Task方法来实现里看到线程有重复的,因为Task底层使用的事线程池,每次Task.Run()不是创建一个新的线程而是从线程池中去查询是否有空闲的线程可以用,而且处理完以后也不会立即侧小,而设置为空闲状态。这就是两者的重要区别.

接下来我们来看下重点async/await

 

简单总结:

  (1)方法签名包含一个 async 修饰符。

  (2)根据约定,异步方法的名称需要以“Async”后缀为结尾。

  (3)3 种返回类型:

    ① Task:返回 TResult 类型。

    ② Task:没有返回值,即返回值为 void。

    ③ void:只适用于异步事件处理程序。

  (4)方法通常包含至少一个 await 表达式,该表达式标记一个点,我们可以成为悬挂点,在该点上,直到等待的异步操作完成,之后的方法才能继续执行。 与此同时,该方法将挂起,并将控制权返回到方法的调用方。

给个示例看下

#region 异步编程测试

        private static void TestAsync()
        {
            Console.WriteLine("异步编程测试");
            Task value = CalAsync(5);
            //处理其他事情
            Console.WriteLine("处理其他事情");
            Console.WriteLine("A");
            Console.WriteLine("B");
            //value.Wait();//等待异步完成后进入主线程的任务 开启时C没有立即打印 关闭时C立即打印
            Console.WriteLine("C");
            Console.WriteLine("异步计算结果:{0}", value.Result);


        }

        private static async Task CalAsync(int i)
        {
            Console.WriteLine("异步start");
            var result = await Task.Run(() => calculate(i));////等待执行完毕
            Console.WriteLine("异步end");
            return result;
        }

        private static async Task CalnewAsync(int i)
        {
            Console.WriteLine("Async Start");
            var result = Task.Run(() => Calculate(i));//执行此方法
            Console.WriteLine("Async End");
            int k = await result;//需要用到上面方法的值时等待
            return k;
        }

        private static int calculate(int i)
        {
            Thread.Sleep(2000);
            for (int j = 0; j < i; j++)
            {
                Console.WriteLine("输出的测试结果{0}", j);
            }
            return 1;
        }

        #endregion

从代码中可以发现执行结果为:

C#笔记(.Net异步编程async/await)3_第1张图片

代码会先执行同步的方法,当调用calAsync异步方法时刚开始还是同步执行,判断到await关键字时进入异步方法同时将控制权放回给主方法TestAnsyc。由于主方法需要用到value.Result所以又等待calAsync异步方法执行完毕后将值打印出来。

这其中的value.wait()方法需要讲解下,如果执行此代码出现的结果是

C#笔记(.Net异步编程async/await)3_第2张图片

可以看出如果执行wait()方法,同步方法执行到wait()时会等待异步方法执行完毕后继续执行主方法中的代码。

其中CalAsync和CalnewAsync两个异步方法,仔细看下有点不同,CalAsync中var result = await Task.Run(() => Calculate(i));

需要等待此方法执行完毕异步方法才会执行此方法内之后的代码,而CalnewAsync中var result = Task.Run(() => Calculate(i));其中的await放到了Console.WriteLine("Async End");这句代码之后来执行int k = await result;也就是说执行此方法后异步方法内此方法之后的代码可以继续执行直到await语句时就需要等待刚才那方法执行完毕才可以往下走,这是一点区别,实际开发中可能会用到.

通过上述讲解.net的异步编程大致概念应该就有了吧。

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