zoukankan      html  css  js  c++  java
  • Async和Await 异步方法

    Async和Await关键字是C#异步编程的核心。通过使用这两个关键字,你可以使用.NET Framework或Windows Runtime的资源创建一个异步方法如同你创建一个同步的方法一样容易。通过使用async和await定义的异步方法,这里被称为异步方法。

    异步方法的特点:

    方法中包含了 async 修饰符。

    一个async方法按照惯例以“Async”结尾。

    返回类型是如下类型之一:

    Task<TResult> 当你的方法有返回值时,TResult即返回值的类型

    Task 当你的方法没有return语句,或者返回值并不参与任何形式的运算(包括赋值操作)。

    Void 当你编写一个异步事件处理时会用到。

    方法通常包括至少一个await的表达式,这意味着该方法在遇到await时不能继续执行,直到等待异步操作完成。在此期间,该方法将被暂停,并且控制权返回到该方法的调用者。

    线程

    异步方法的目的是不阻塞操作。在async方法中, await任务在执行的过程中,并不会阻塞当前的线程,其余的方法可以继续执行,控制权将会移交到async方法的调用者。

    async和await关键字并不会创建额外的线程,async方法不会去请求多线程操作。真正创建线程的操作是由Task.Run()实现的,一个async方法并不是在他自己的线程上执行的,只有当方法被激活时,才会使用当前线程的上下文和处理时间。

    async方法要比BackgroundWorker更实用,而且使用起来更简单而且不用去过多的考虑竞态冲突神马的。async方法会将运行中的代码依据某些算法进行合理的拆分,并传递给线程池,这也是BackgroundWorker不能比的。

    Async和Await

    如果需要使用async或者await指定一个异步方法,我们需要注意一下两点:

    用async标记的异步方应该使用await关键子来制定挂起点。await操作符会告诉编译器,这个async方放在完成之前,后面的代码无法继续执行,同时,控制权转移到async方法的调用者。

    标记为async的方法,调用时应使用await。

    一个async方法里通常包含一个或多个的对应的await操作符,但如果没有await表达式也不会导致编译错误。但如果调用一个async方 法,却不使用await关键字来标记一个挂起点的话,程序将会忽略async关键字并以同步的方式执行。编译器会对类似的问题发出警告。

    返回类型和参数

    在.NET Framework编程中,一个async方法通常返回的类型是Task或者Task<TResult>。在异步方法中,await操作符作用于从另外一个异步方法返回的Task。

    如果指定Task<TResult>为返回结果,那么这个方法必须包含return指定的TResult结果的语句。

    如果使用Task作为返回值,那么这个方法应该不存在使用return语句返回结果的代码,或者返回的结果不参与任何运算(包括赋值操作)。

    每一个返回的task都代表一个正在执行的工作,task包装的信息中包含了这个异步方法的执行时的状态,最终的结果,或者处理过程中抛出的异常。

    如果返回值为void,这种类型主要使用于定义事件处理。异步事件通常被认为是一系列异步操作的开始。使用void返回类型不需要await,而且调用void异步方法的函数不会捕获方法抛出的异常。

    另外,async方法不能使用ref或者out参数,但是可以调用含有这些参数的方法。

    命名约定

    按照约定,你应该在异步方法的名称后面追加“Async”用以标记此方法。但是在event,基类和接口中不需要遵守约定,就像本文例子中event处理函数Button1_Click一样。

    例子:

    using System;
    using System.Threading.Tasks;
    
    namespace AsyncAndAwait {
        class Program {
            static void Main(string[] args) {
                DisplayValue();
                Console.Write("Myclass End");
                Console.Read();
            }
    
    
            public static Task<double> GetvalueAsync(double num1, double num2) {
                return Task.Run(() => {
                    for(int i = 0; i < 10000; i++) {
                        num1 = num1 / num2;
    
                    }
                    return num1;
    
    
                });
            }
            public static async void DisplayValue() {
                double result = await GetvalueAsync(1234.5, 1.01);
    
                Console.Write("Value is:" + result);
    
            }
        }
    }
    
    人生短短数十载,最要紧的是满足自己,不是讨好他人。 ——亦舒《美丽新世界》
  • 相关阅读:
    linux mysql开启远程链接
    Nginx 下无法读取session 导致 thinkphp验证码错误
    Nginx 开启 path_info功能
    让chrome打开手机网页
    vue 组件和全局组件的注册、使用
    Vue 导入文件import、路径@和.的区别
    vue 打包路径不对设置方法
    id
    Ajax GET 和 POST 的区别
    前端笔试题汇总 2018/12/04 (2)
  • 原文地址:https://www.cnblogs.com/jerrys/p/5144353.html
Copyright © 2011-2022 走看看