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一样。

    例子:

     1 using System;
     2 using System.Threading.Tasks;
     3  
     4 namespace AsyncAndAwait {
     5     class Program {
     6         static void Main(string[] args) {
     7             DisplayValue();
     8             Console.Write("Myclass End");
     9             Console.Read();
    10         }
    11  
    12  
    13         public static Task<double> GetvalueAsync(double num1, double num2) {
    14             return Task.Run(() => {
    15                 for(int i = 0; i < 10000; i++) {
    16                     num1 = num1 / num2;
    17  
    18                 }
    19                 return num1;
    20  
    21  
    22             });
    23         }
    24         public static async void DisplayValue() {
    25             double result = await GetvalueAsync(1234.5, 1.01);
    26  
    27             Console.Write("Value is:" + result);
    28  
    29         }
    30     }
    31 }
  • 相关阅读:
    document.getElementById("mytxt").style.left=""style.left在IE的FF中注意
    asp.net 用户控件中 使用相对路径的解决方法 图片路径问题(用户控件、图片路径) ,ResolveUrl
    探索 Block (一) (手把手讲解Block 底层实现原理)
    iOS 多线程开发 (概念与API简介)
    iOS 性能小点
    iOS runtime (二)(runtime学习之AutoCoding源码分析)
    探索 NSRunLoop (二)(NSRunLoop 自己动手实现SimpleRunLoop)
    iOS NSNotificationCenter (自己实现一个通知中心XMCNotificationCenter)
    iOS runtime (三)(runtime学习之YYModel源码分析)
    iOS runtime(一)(runtime 分析理解)
  • 原文地址:https://www.cnblogs.com/yanglang/p/9602178.html
Copyright © 2011-2022 走看看