c# 异步编程 学习笔记

            /*异步编程
             * 什么是异步编程,就是在不影响主程序线程的情况下,调用新的线程,去处理新的任务。让主程序县城可以继续执行其他任务。通常用在
             * 耗时比较长的任务上,查询数据库,打开大型文件
             * 
             * 和同步的区别:
             * 同步:执行完一个操作后主程序才能执行下一个操作,有着固定的顺序
             * 异步:在主程序执行一个操作时,异步操作可以在同时进行
             * 本质就是重新开启了一个线程 主程序线程和方法线程并行执行
             * 
             * 和多线程的区别:
             * 首先,线程是程序提供的一种逻辑功能,他需要cpu的资源
             * 异步操作不需要额外的线程,自然也就没有CPU的压力,使用回调的方式进行处理,而且对于共享变量的使用较少,不容易造成死锁,
             * 但是顺序不符合普通人的思维
             * 多线程需要启动额外的线程,需要消耗CPU资源。处理程序是顺序执行的。额外的线程容易对程序造成负担,共享变量容易造成死锁
             * 
             * 异步模式
             * 1异步模式
             * 2基于事件的异步模式
             * 3基于任务的异步模式
             * 

             */


下面举一个最普通的异步执行的例子

定义一个文件读取类

   class fileReader
    {
        /// <summary>
        /// 缓存池
        /// </summary>
        byte[] buffer;
        /// <summary>
        /// 缓存区大小
        /// </summary>
        private int buffsize;
        public int Buffsize { get => buffsize; set => buffsize = value; }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="buffsize">缓存区大小 </param>
        public fileReader( int buffsize)
        {
            Buffsize = buffsize;
            this.buffer = new byte[Buffsize];
        }


        /// <summary>
        /// 同步读取文件
        /// </summary>
        /// <param name="path">文件路径</param>
        public void SynsReadFile(string path)
        {
            Console.WriteLine("syns read File now begin");


            if (File.Exists(path))
            {
                FileStream fs = new FileStream(path,FileMode.Open);
                fs.Read(buffer, 0, Buffsize);
                string output = Encoding.UTF8.GetString(buffer);
                Console.WriteLine("now the file is " + output);
            }
        }
        /// <summary>
        /// 异步读取文件
        /// </summary>
        /// <param name="path">文件路径</param>
        public void AsynReadFile(string path)
        {
            Console.WriteLine("asyn read file now begin");
            if (File.Exists(path))
            {
                FileStream fs = new FileStream(path, FileMode.Open);
                fs.BeginRead(buffer, 0, Buffsize,AsyncReadFileCallBack,fs);
            }
        }
        /// <summary>
        /// 异步读取的回调
        /// </summary>
        /// <param name="ar"></param>
        public void AsyncReadFileCallBack(IAsyncResult ar)
        {
            FileStream fs = ar.AsyncState as FileStream;


            if (fs != null)
            {
                Thread.Sleep(1000);


                fs.EndRead(ar);
                fs.Close();


                string output = Encoding.UTF8.GetString(buffer);
                Console.WriteLine("now the file is " + output);
            }
        }
    }

然后再主程序中

        static void Main(string[] args)
        {

  //同步执行和异步执行的例子
            fileReader reader = new fileReader(1024);


            string path = "C:\\Users\\v-chli1\\Desktop\\e-mail.txt";


            Console.WriteLine(" put an enter to start reading file");
            Console.ReadLine();
            Console.WriteLine(DateTime.Now);
            //reader.SynsReadFile(path);
            reader.AsynReadFile(path);


            Console.WriteLine("Next step");
            testMethod();

}

        /// <summary>
        /// 测试方法
        /// </summary>
        static void testMethod()
        {
            Thread.Sleep(1000);
            Console.WriteLine(DateTime.Now);
            for (int i = 0; i<=777;i++)
            {
                 if (i % 777 == 0)
                     Console.WriteLine("the number is " + i);
            }
        }



      接下来是使用async 和await关键字的,基于任务的异步编程 方法

             * async 和await 关键字
             *  async 修饰符只能用于返回Task和void的方法
             *  await 只能用于返回Task的方法
             *  
             *  一个方法 添加了async 就表示这是一个异步方法
             *  await 关键词用在调用方法事时,处理Async 后缀的异步方法
             *  task.run 会创建一个线程池里的线程
             *  
             *  
             *  Async方式,使用Async标记的方法为异步方法,用Await标记方法c表示方法内需要耗时的操作。主线程碰到await时会立即返回,继续以非阻塞形式执行主线程下面的逻辑。当await耗时操作完成时,继续执行Async方法下面的逻辑
             *  使用这两个关键字时
             *  1,首先创建一个普通方法(也可以省略直接写在异步化方法里)
             *  2,创建一个task方法,方法名需要async作为后缀 ,返回值需要是Task或者Void,也可以Task<泛型>。然后用task.run 返回一个任务。调用普通方法或者直接将方法写入
             *  3. 创建异步方法,需要用关键字async,调用前面的task 方法时,需要使用await 关键字,通知主线程去执行其他代码。等await 方法结束之后,才会继续带哦用异步方法中的后面
             *  的代码
             *  4.如果有continueWith 方法,则结束后继续执行此代码块中的代码
             * 

//异步代码

   public static string Greeting(string name)
        {
            Thread.Sleep(2000);
            return string.Format("Hello , {0}", name);
        }
        /// <summary>
        /// 创建任务
        /// </summary>
        /// <param name="name">参数</param>
        /// <returns></returns>
        static Task<string> GreetingAsync(string name)
        {
            return Task.Run<string>(() =>
             {
                 return Greeting(name);
             });
        }
        /// <summary>
        /// 调用异步方法
        /// </summary>
        private async static void callerWithAsync()
        {
            string result = await GreetingAsync("bob");
            Console.WriteLine(result);
        }
        /// <summary>
        /// continuewith 方法
        /// </summary>
        private static void CallerWithContinuationTask()
        {
            Task<string> t1 = GreetingAsync("david");
            t1.ContinueWith(
                t => {
                    string result = t.Result;
                    Console.WriteLine(result+"123");
                }
                );
        }


        private static  async void MultipleAsyncMethods()
        {
            string s1 = await GreetingAsync("logan");
            string s2 = await GreetingAsync("charles");
            Console.WriteLine("methods finished " + s1 +" "+ s2);
        }
        private static async void MultipleAsyncMethodsWithCombinator()
        {
            Task<string> s1 =  GreetingAsync("logan1");
            Task<string> s2 =  GreetingAsync("charles1");
            await Task.WhenAll(s1,s2);
            Console.WriteLine("methods finished " + s1.Result + " " + s2.Result);
        }
        private static async void MultipleAsyncMethodsWithCombinator2()
        {
            Task<string> s1 = GreetingAsync("logan2");
            Task<string> s2 = GreetingAsync("charles2");
            await Task.WhenAny(s1, s2);
            Console.WriteLine("methods finished " + s1.Result + " " + s2.Result);
        }

然后主程序中的代码

 static void Main(string[] args)
        {

  MultipleAsyncMethodsWithCombinator2();
            callerWithAsync();
            CallerWithContinuationTask();
            MultipleAsyncMethods();
            MultipleAsyncMethodsWithCombinator();

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值