• 【笔记】记一次.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关键字时则该方法就是一整块没有所谓的划分,会在同步中运行,在同步中完成。

  • 相关阅读:
    第七届河南省赛F.Turing equation(模拟)
    第八届acm省赛 A挑战密室(模拟)
    展开字符串(dfs)
    排名(水题)
    Identity Card(水题)
    Dropping Balls (二叉树+思维)
    SQL学习——IN运算符
    SQL学习——BETWEEN运算符
    SQL学习——LIKE运算符
    【数字图像处理】灰度转换算法
  • 原文地址:https://www.cnblogs.com/x-poior/p/7113049.html
Copyright © 2020-2023  润新知