说说C#的async和await的具体用法

C# 5.0中引入了async 和 await。这两个关键字可以让你更方便的写出异步代码。

看个例子:

public class MyClass
{
  public MyClass()
  {
    DisplayValue(); //这里不会阻塞
    System.Diagnostics.Debug.WriteLine("MyClass() End.");
  }
  public Task<double> GetValueAsync(double num1, double num2)
  {
    return Task.Run(() =>
    {
      for (int i = 0; i < 1000000; i++)
      {
        num1 = num1 / num2;
      }
      return num1;
    });
  }
  public async void DisplayValue()
  {
    double result = await GetValueAsync(1234.5, 1.01);//此处会开新线程处理GetValueAsync任务,然后方法马上返回
    //这之后的所有代码都会被封装成委托,在GetValueAsync任务完成时调用
    System.Diagnostics.Debug.WriteLine("Value is : " + result);
  }
}

上面在MyClass的构造函数里调用了async关键字标记的异步方法DisplayValue(),DisplayValue()方法里执行了一个await关键字标记的异步任务GetValueAsync(),这个异步任务必须是以Task或者Task<TResult>作为返回值的,而我们也看到,异步任务执行完成时实际返回的类型是void或者TResult,DisplayValue()方法里await GetValueAsync()之后的所有代码都会在异步任务完成时才会执行。

DisplayValue()方法实际执行的代码如下:

public void DisplayValue()
{
  System.Runtime.CompilerServices.TaskAwaiter<double> awaiter = GetValueAsync(1234.5, 1.01).GetAwaiter();
  awaiter.OnCompleted(() =>
    {
      double result = awaiter.GetResult();
      System.Diagnostics.Debug.WriteLine("Value is : " + result);
    });
}

可以看到,async和await关键字只是把上面的代码变得更简单易懂而已。

程序的输出如下:

MyClass() End.
Value is : 2.47032822920623E-322

以下是我写的一个静态类,可以方便将一个普通Function执行异步调用:

public static class TaskAsyncHelper
{
  /// <summary>
  /// 将一个方法function异步运行,在执行完毕时执行回调callback
  /// </summary>
  /// <param name="function">异步方法,该方法没有参数,返回类型必须是void</param>
  /// <param name="callback">异步方法执行完毕时执行的回调方法,该方法没有参数,返回类型必须是void</param>
  public static async void RunAsync(Action function, Action callback)
  {
    Func<System.Threading.Tasks.Task> taskFunc = () =>
    {
      return System.Threading.Tasks.Task.Run(() =>
      {
        function();
      });
    };
    await taskFunc();
    if (callback != null)
      callback();
  } 

  /// <summary>
  /// 将一个方法function异步运行,在执行完毕时执行回调callback
  /// </summary>
  /// <typeparam name="TResult">异步方法的返回类型</typeparam>
  /// <param name="function">异步方法,该方法没有参数,返回类型必须是TResult</param>
  /// <param name="callback">异步方法执行完毕时执行的回调方法,该方法参数为TResult,返回类型必须是void</param>
  public static async void RunAsync<TResult>(Func<TResult> function, Action<TResult> callback)
  {
    Func<System.Threading.Tasks.Task<TResult>> taskFunc = ()=>
      {
        return System.Threading.Tasks.Task.Run(()=>
          {
            return function();
          });
      };
    TResult rlt = await taskFunc();
    if(callback != null)
      callback(rlt);
  }
}

使用很简单,将方法名作为参数传进去就行了,最常用的是把很耗时的序列化函数传进去,以免阻塞UI进程,造成卡顿现象,影响用户体验。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 详解C#中的Async和Await用法

    这篇文章由Filip Ekberg为DNC杂志编写. 自跟随着.NET 4.5 及Visual Studio 2012的C# 5.0起,我们能够使用涉及到async和await关键字的新的异步模式.有很多不同观点认为,比起以前我们看到的,它的可读性和可用性是否更为突出.我们将通过一个例子来看下它跟现在的怎么不同. 线性代码vs非线性代码 大部分的软件工程师都习惯用一种线性的方式去编程,至少这是他们开始职业生涯时就被这样教导.当一个程序使用线性方式去编写,这意味着它的源代码读起来有的像Figure

  • 详解C#中 Thread,Task,Async/Await,IAsyncResult的那些事儿

    说起异步,Thread,Task,async/await,IAsyncResult 这些东西肯定是绕不开的,今天就来依次聊聊他们 1.线程(Thread) 多线程的意义在于一个应用程序中,有多个执行部分可以同时执行:对于比较耗时的操作(例如io,数据库操作),或者等待响应(如WCF通信)的操作,可以单独开启后台线程来执行,这样主线程就不会阻塞,可以继续往下执行:等到后台线程执行完毕,再通知主线程,然后做出对应操作! 在C#中开启新线程比较简单 static void Main(string[]

  • 说说C#的async和await的具体用法

    C# 5.0中引入了async 和 await.这两个关键字可以让你更方便的写出异步代码. 看个例子: public class MyClass { public MyClass() { DisplayValue(); //这里不会阻塞 System.Diagnostics.Debug.WriteLine("MyClass() End."); } public Task<double> GetValueAsync(double num1, double num2) { re

  • .NET中的async和await关键字使用及Task异步调用实例

    其实早在.NET 4.5的时候M$就在.NET中引入了async和await关键字(VB为Async和Await)来简化异步调用的编程模式.我也早就体验过了,现在写一篇日志来记录一下顺便凑日志数量(以后面试之前可以用这个"复习"一下). (一)传统的异步调用 在比较"古老"的C#程序中经常可以看到IAsyncResult.BeginInvoke之类的异步调用"踪迹".先来简单的复习一下吧. 假如我们有一个方法生成字符串,而生成这个字符串需要10秒

  • 浅谈Async和Await如何简化异步编程(几个实例让你彻底明白)

    引言 C#5.0中async和await两个关键字,这两个关键字简化了异步编程,之所以简化了,还是因为编译器给我们做了更多的工作,下面就具体看看编译器到底在背后帮我们做了哪些复杂的工作的. 同步代码存在的问题 对于同步的代码,大家肯定都不陌生,因为我们平常写的代码大部分都是同步的,然而同步代码却存在一个很严重的问题,例如我们向一个Web服务器发出一个请求时,如果我们发出请求的代码是同步实现的话,这时候我们的应用程序就会处于等待状态,直到收回一个响应信息为止,然而在这个等待的状态,对于用户不能操作

  • 关于async和await的一些误区实例详解

    微软官方的MSDN上说async和await是"异步",但是不少人(包括笔者自己)都有一些误区需要澄清:为什么await语句之后没有执行?不是异步吗? 先举一个示例代码如下: public partial class Form1 : Form { public async Task Processing() { await Task.Delay(5000); label1.Text = "Succuessful"; } public Form1() { Initia

  • .net4.5使用async和await异步编程实例

    关于异步编程的简单理解: 在.NET4.5中新增了异步编程的新特性async和await,使得异步编程更为简单.通过特性可以将这项复杂的工作交给编译器来完成了.之前传统的方式来实现异步编程较为复杂,这样对于程序猿来说处理起来比较困难,调试也没那么方便,后续的维护工作也比较痛苦. Async和Await关键字是C#异步编程的核心.通过使用这两个关键字,你可以使用.NET Framework 或 Windows Runtime的资源创建一个异步方法如同创建一个同步方法一样容易. 接下来通过VS201

  • async and await 的入门基础操作

    如果有几个Uri,需要获取这些Uri的所有内容的长度之和,你会如何做? 很简单,使用WebClient一个一个的获取uri的内容长度,进行累加. 也就是说如果有5个Uri,请求的时间分别是:1s 2s 3s 4s 5s. 那么需要的时间是:1+2+3+4+5=(6*5)/2=15. 如果采用并行计算的话,结果可能是这样: 总时间长度是5s. 为了演示效果,需要下面3个页面: 其中SlowPage 的Page_load代码如下: 复制代码 代码如下: protected void Page_Loa

  • 详解Node.js中的Async和Await函数

    在本文中,你将学习如何使用Node.js中的async函数(async/await)来简化callback或Promise. 异步语言结构在其他语言中已经存在了,像c#的async/await.Kotlin的coroutines.go的goroutines,随着Node.js 8的发布,期待已久的async函数也在其中默认实现了. Node中的async函数是什么? 当函数声明为一个Async函数它会返回一个 AsyncFunction 对象,它们类似于 Generator 因为执可以被暂停.唯

  • 浅谈C#中的Async和Await的用法详解

    众所周知C#提供Async和Await关键字来实现异步编程.在本文中,我们将共同探讨并介绍什么是Async 和 Await,以及如何在C#中使用Async 和 Await. 同样本文的内容也大多是翻译的,只不过加上了自己的理解进行了相关知识点的补充,如果你认为自己的英文水平还不错,大可直接跳转到文章末尾查看原文链接进行阅读. 写在前面 自从C# 5.0时代引入async和await关键字后,异步编程就变得流行起来.尤其在现在的.NET Core时代,如果你的代码中没有出现async或者await

  • 详解koa2学习中使用 async 、await、promise解决异步的问题

    关键词:async .await.promise 这三个东西 可以优雅的解决异步问题.在学习koa2的时候遇到了获取数据后再进行模板渲染的异步问题.在查找各种资料后成功的解决了该问题,现在写个笔记记录一下. 先说一下async.await,第一次见到这两个词是在学习vue的时候.因为前端在写代码的时候经常的会遇到向后台请求数据这样的场景,等待数据返回才可以进行下一步的操作.这就不得不处理异步这种情况. async.await基本的语法就是: let asyncFn = async()=> { l

随机推荐