• 异步 async & await


    1 什么是异步

    异步的另外一种含义是计算机多线程的异步处理。与同步处理相对,异步处理不用阻塞当前线程来等待处理完成,而是允许后续操作,直至其它线程将处理完成,并回调通知此线程。

    2 异步场景

    • l  不涉及共享资源,或对共享资源只读,即非互斥操作
    • l  没有时序上的严格关系
    • l  不需要原子操作,或可以通过其他方式控制原子性
    • l  常用于IO操作等耗时操作,因为比较影响客户体验和使用性能
    • l  不影响主线程逻辑

     

    3 异步编写 C#

    Async  await关键字

     Async method

    三种返回类型

    –      void (public async void InvokeAsync();) (应仅用于事件处理程序)

    –      Task (pubic async Task InvokeAsync();)

    –      Task<T> (public async Task<string> InvokeAsync();)

    await 不会开启新的线程,当前线程会一直往下走直到遇到真正的Async方法(比如说HttpClient.GetStringAsync),这个方法的内部会用Task.Run或者Task.Factory.StartNew 去开启线程。也就是如果方法不是.NET为我们提供的Async方法,我们需要自己创建Task,才会真正的去创建线程

    static void Main(string[] args)
            {
                Console.WriteLine("Main Thread Id: {0}
    ", Thread.CurrentThread.ManagedThreadId);
                Test();
                Console.ReadLine();
            }
    
            static async Task Test()
            {
                Console.WriteLine("Before calling GetName, Thread Id: {0}
    ", Thread.CurrentThread.ManagedThreadId);
                var name = GetName();   //我们这里没有用 await,所以下面的代码可以继续执行
                                        // 但是如果上面是 await GetName(),下面的代码就不会立即执行,输出结果就不一样了。
                Console.WriteLine("End calling GetName.
    ");
                Console.WriteLine("Get result from GetName: {0}", await name);
            }
    
            static async Task<string> GetName()
            {
                // 这里还是主线程
                Console.WriteLine("Before calling Task.Run, current thread Id is: {0}", Thread.CurrentThread.ManagedThreadId);
                return await Task.Run(() =>
                {
                    Thread.Sleep(1000);
                    Console.WriteLine("'GetName' Thread Id: {0}", Thread.CurrentThread.ManagedThreadId);
                    return "Jesse";
                });
            }

    1. 进入主线程开始执行
    2. 调用async方法,返回一个Task,注意这个时候另外一个线程已经开始运行,也就是GetName里面的 Task 已经开始工作了
    3. 主线程继续往下走
    4. 第3步和第4步是同时进行的,主线程并没有挂起等待
    5. 如果另一个线程已经执行完毕,name.IsCompleted=true,主线程仍然不用挂起,直接拿结果就可以了。如果另一个线程还同有执行完毕, name.IsCompleted=false,那么主线程会挂起等待,直到返回结果为止。

    使用注意:

    • 异步代码使用 Task<T> 和 Task,它们是对后台所完成的工作进行建模的构造。
    • async 关键字将方法转换为异步方法,这使你能在其正文中使用 await 关键字。
    • 应用 await 关键字后,它将挂起调用方法,并将控制权返还给调用方,直到等待的任务完成。
    • 仅允许在异步方法中使用 await。
    • async 方法需在其主体中具有 await 关键字,否则它们将永不暂停!
    • 应将“Async”作为后缀添加到所编写的每个异步方法名称中。
    • await 语句 (await Task)
    Task task = client.SendMailAsync(mailMessage);
    
    await task;

    await 表达式

    Task<byte[]> task = webClient.DownloadDataTaskAsync(uri);
    
    byte[] result = await task;
    
    OR
    
    byte[] result = await webClient.DownloadDataTaskAsync(uri);

    部分内容引用来自

    http://www.cnblogs.com/jesse2013/p/async-and-await.html

  • 相关阅读:
    How Google TestsSoftware
    How Google TestsSoftware
    How Google TestsSoftware
    How Google TestsSoftware
    How Google Tests Software
    月薪3万的程序员都避开了哪些坑
    关于BUG率的计算和它的实际意义的思考
    fastJSON☞JSONParameters☞时区的修改☞时间最后有一个"Z"
    基础知识系列☞C#中数组Array、ArrayList和List三者的区别
    WCF--提示:异常消息为“传入消息的消息格式不应为“Raw”。此操作的消息格式应为 'Xml', 'Json'。
  • 原文地址:https://www.cnblogs.com/dreamtaker/p/8126223.html
Copyright © 2020-2023  润新知