您的位置:首页 > 编程语言 > C#

c# 异步编程 学习笔记

2017-03-27 17:23 471 查看
            /*异步编程

             * 什么是异步编程,就是在不影响主程序线程的情况下,调用新的线程,去处理新的任务。让主程序县城可以继续执行其他任务。通常用在

             * 耗时比较长的任务上,查询数据库,打开大型文件

             * 

             * 和同步的区别:

             * 同步:执行完一个操作后主程序才能执行下一个操作,有着固定的顺序

             * 异步:在主程序执行一个操作时,异步操作可以在同时进行

             * 本质就是重新开启了一个线程 主程序线程和方法线程并行执行

             * 

             * 和多线程的区别:

             * 首先,线程是程序提供的一种逻辑功能,他需要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 返回一个任务。调用普
4000
通方法或者直接将方法写入

             *  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();

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息