【笔记】记一次.net语法await和async的异步编程实验与笔记。

2.foreach使用ef操作,使用方式注意:

  List<string> l1 = new List<string>();
            l1.Add("1");
            l1.Add("2");
            l1.Add("3");
            l1.Add("4");

            foreach (var ss in l1)
            {
                User models = await repo.GetAll<User>().SingleOrDefaultAsync(x => x.Account == ss);
            }
            //l1.ToList().ForEach(q=>{
            //    User models = await repo.GetAll<User>().SingleOrDefaultAsync(x => x.Account == q);
            //});//这样写会报上下文不能被不同线程访问的异常

1.实践代码全记录:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace await_测试
{
    class Program
    {
        static void Main(string[] args)
        { 
            testc();
            Console.Read();
        }

        //async具有僵尸病毒般的传染性,async 会感染周围的代码,直到顶层。其实我们只需要顺其自然,让所有代码都传染上异步特性即可。
        //如果我们使用Task.Wait 或者Task.Result去试图阻塞async 的传播,往往便会自找苦吃。
        //这个往往是刚接触async 异步的人最容易犯的错误,这样往往会导致死锁。互相等待。
        static async void testc()
        {

            ////----写法1.
            //Stopwatch sw = new Stopwatch();
            //sw.Start();
            //var d1 = delay10();//立刻执行,等待取回结果
            //var d2 = delay20();//立刻执行,等待取回结果
            //var d3 = delay30();//立刻执行,等待取回结果 
            ////依次取结果,取结果时间很短
            //await d1;// 单条语句的确没有意义,但类似本场景多条语句的话,异步并发执行的优势就出来了。总耗时是最长耗时的那个值。
            //await d2;// 第一个执行完,取不取结果是另一回事。
            //await d3;// 并发执行,【2】需要获得值的时候,禁用Task.Wait or Task.Result 用 await,防止 异常信息以及防止死锁
            //sw.Stop();
            //Console.WriteLine("结束");
            //Console.WriteLine("耗时:" + sw.ElapsedMilliseconds);
            ////结论:互不影响,同时进行,耗时约25秒


            //----写法11.
            Stopwatch sw = new Stopwatch();
            sw.Start();
            var d1 = delay10();//立刻执行,等待取回结果
            var d2 = delay20();//立刻执行,等待取回结果
            var d3 = delay30();//立刻执行,等待取回结果 
            //依次取结果,取结果时间很短
            Console.WriteLine( d1.Result);// 单条语句的确没有意义,但类似本场景多条语句的话,异步并发执行的优势就出来了。总耗时是最长耗时的那个值。
            Console.WriteLine( d2.Result);// 第一个执行完,取不取结果是另一回事。
            Console.WriteLine( d3.Result);// 并发执行,【2】需要获得值的时候,禁用Task.Wait or Task.Result 用 await,防止 异常信息以及防止死锁
            sw.Stop();
            Console.WriteLine("结束");
            Console.WriteLine("耗时:" + sw.ElapsedMilliseconds);
            //结论:互不影响,同时进行,耗时约25秒



            ////----写法2.
            //Stopwatch sw = new Stopwatch();
            //sw.Start();
            //await delay10();//线性执行,线性取回结果
            //await delay20();//线性执行,线性取回结果
            //await delay30();//线性执行,线性取回结果
            //sw.Stop();
            //Console.WriteLine("耗时:" + sw.ElapsedMilliseconds);
            ////结论:耗时是43秒,线性按行执行,总耗时大于三个线程耗时之和。



            ////----写法3.
            //Stopwatch sw = new Stopwatch();
            //sw.Start(); 
            //Task t1 = delay10();//立刻执行, 
            //Task t2= delay20(); //立刻执行, 
            //Task t3 = delay30();//立刻执行, 
            //Task[] tk = { t1, t2, t3 };
            //await Task.WhenAll(tk);

            //sw.Stop();
            //Console.WriteLine("耗时:" + sw.ElapsedMilliseconds);
            //////结论:互不影响,同时进行,耗时约25秒



            //----写法4.
            //Stopwatch sw = new Stopwatch();
            //sw.Start(); 
            //Task t1 = delay10();//立刻执行, 
            //Task t2 = delay20(); //立刻执行, 
            //Task t3 = delay30();//立刻执行, 
            //Task[] tk = { t1, t2, t3 };
            //Task.WaitAll(tk);
            //注意:【1】需要等待所有任务完成 禁用Task.WaitAll 用 await Task.WhenAll,防止 异常信息以及防止死锁
            //http://www.cnblogs.com/bnbqian/p/4513192.html 
            //sw.Stop();
            //Console.WriteLine("耗时:" + sw.ElapsedMilliseconds);
            //////结论:互不影响,同时进行,耗时约25秒


            ////总结: 进化过程:Thread+线程同步信号量  ->  Task  -> async&await

        }

        static async Task<string> delay10()
        {
            Task<string> t = new Task<string>(() => 
            {
                Thread.Sleep(25000);//小失误。需要等待请用:Task.Delay(),禁用Thread.Sleep,防止 异常信息以及防止死锁
                return "25000";
            });
            t.Start();
            string tr = await t;
            return tr;//  Console.WriteLine(tr);
        }

        static async Task<string> delay20()
        {
            Task<string> t = new Task<string>(() => { Thread.Sleep(10000); return "10000"; });
            t.Start();
            string tr = await t;
            return tr;// Console.WriteLine(tr);
        }

        static async Task<string> delay30()
        {
            Task<string> t = new Task<string>(() => { Thread.Sleep(3600); return "3600"; });
            t.Start();
            string tr = await t;
            return tr;// Console.WriteLine(tr);
        }
    }
}

2.实践笔记:

1.无论方法是同步还是异步都可以用async关键字来进行标识,因为用async标识只是显示表明在该方法内可能会用到await关键字使其变为异步方法,而且将该异步方法进行了明确的划分,只有用了await关键字时才是异步操作,其余一并为同步操作。

2.当用async标识方法时只是显示告诉编译器在该方法中await关键字可能会被用到,当执行到await关键字开始处于挂起的状态知道异步动作执行完成才恢复。

3.用async标识方法并不会影响方法运行完成是否是同步或者异步,相反,它能够将方法划分成多块,有可能有些在异步中运行,以至于这些方法是异步完成的,而划分异步和同步方法的边界就是使用await关键字。也就是说如果在方法中未用到await关键字时则该方法就是一整块没有所谓的划分,会在同步中运行,在同步中完成。

原文地址:https://www.cnblogs.com/x-poior/p/7113049.html