C#中的异步编程:await和async

根据代码示例来学习,

  1. 创建一个函数来模拟时间消耗的方法,此处为GetSomeThing函数。
  2. 要使用异步编程,需要使用一个async修饰的方法来包装调用GetSomeThing函数,此函数的返回值为Task类型,该类型表示进行并行运算的任务引用。此处示例为ConsumeManyTime函数。
  3. 现在就可以直接使用异步方式了,参考TestOne()函数中的代码,其实就是直接调用第二步中的函数ConsumeManyTime();

总结:
异步编程虽然示例三步,但是实际上就是两步的事情,第一步是模拟应用,跟异步编程本身没有关系,第二步包装一个Task返回类型的async修饰的方法,该方法实际调用应用函数,第三步调用第二步的方法,从而执行对模拟应用的异步执行。

附加:
除了异步编程以外,C#还提供了并发编程相关功能,极大简化了并发任务的开发,可以让开发人员无需创建线程池以及管理线程这些工作,就可以直接使用并发开发带来的优势。 示例代码见Testpallral()

代码如下

class Program
    {

        static int i = 0;
        //模拟耗时的运算或者IO
        public static bool GetSomeThing(string a)
        {
            Thread.Sleep((new Random()).Next()%10*1000);
            i++;
            Console.WriteLine(DateTime.Now.ToLongTimeString()+"5-" + Thread.GetCurrentProcessorId().ToString());
            return true;
        }
        //生成一个task类型,其中包装调用GetSomeThing
        public static Task<bool> GetSomeThingAsync(string a)
        {
            return Task.Run<bool>(()=> { return GetSomeThing(a); }
            );
        }
    //方式1:包装给调用方使用的方法,使用async修饰,因为里面有await。 调用方执行到await会立即返回,后续的内容不再直接调用, await之后的方法都会在可能在其他线程中使用,
    public async static void ConsumeManyTime()
    {
        Console.WriteLine(DateTime.Now.ToLongTimeString() + "3-" +Thread.GetCurrentProcessorId().ToString());
        bool result = await GetSomeThingAsync("test");
        Console.WriteLine(DateTime.Now.ToLongTimeString() + "4-" +Thread.GetCurrentProcessorId().ToString());
    }
    //方式2:这种调用方式是在异步执行完毕后,可以继续执行预定的后续函数,可以理解为一种回调机制。
    public static void ContinueTaskWithConsumeManyTime()
    {
        Task<bool> t1 = GetSomeThingAsync("test");
        t1.ContinueWith(t => { Console.WriteLine("after await finished " + t.Result + " " + Thread.GetCurrentProcessorId().ToString() + " " + i.ToString()); });
    }
    //方式3:多任务等待方式
    public static async void TaskWhenConsumeManyTime()
    {
        Task<bool> t1 = GetSomeThingAsync("test");
        Task<bool> t2 = GetSomeThingAsync("test");
        await Task.WhenAll(t1, t2);
        Console.WriteLine(DateTime.Now.ToLongTimeString() + "6-" + Thread.GetCurrentProcessorId().ToString());

    }

    //async 和await的基本使用
    public static void TestOne()
    {
        Console.WriteLine(DateTime.Now.ToLongTimeString() + "1-" + Thread.GetCurrentProcessorId().ToString());
        ConsumeManyTime();
        ConsumeManyTime();
        Console.WriteLine(DateTime.Now.ToLongTimeString() + "2-" + Thread.GetCurrentProcessorId().ToString());
        Console.WriteLine("继续输入");
        while (Console.ReadLine() != "stop")
        {
            Console.WriteLine("继续输入");
        }
    }

    public static void TestWithContinue()
    {
        Console.WriteLine(DateTime.Now.ToLongTimeString() + "1-" + Thread.GetCurrentProcessorId().ToString());
        ContinueTaskWithConsumeManyTime();
        ContinueTaskWithConsumeManyTime();
        Console.WriteLine(DateTime.Now.ToLongTimeString() + "2-" + Thread.GetCurrentProcessorId().ToString());
        Console.WriteLine("继续输入");
        while (Console.ReadLine() != "stop")
        {
            Console.WriteLine("继续输入");
        }
    }

    public static void TestWhen()
    {
        Console.WriteLine(DateTime.Now.ToLongTimeString() + "1-" + Thread.GetCurrentProcessorId().ToString());
        TaskWhenConsumeManyTime();

        Console.WriteLine(DateTime.Now.ToLongTimeString() + "2-" + Thread.GetCurrentProcessorId().ToString());
        Console.WriteLine("继续输入");
        while (Console.ReadLine() != "stop")
        {
            Console.WriteLine("继续输入");
        }
    }

    public static  void Testpallral()
    {
        ParallelLoopResult result =

              Parallel.For(0, 100, async (int i) =>

              {

                  Console.WriteLine(DateTime.Now.ToLongTimeString() + "{0}, task: {1}, thread: {2}", i,

                  Task.CurrentId, Thread.CurrentThread.ManagedThreadId);

                  await Task.Delay(10);
                  Console.WriteLine(DateTime.Now.ToLongTimeString() + "after delay");

              });

        while (Console.ReadLine() != "stop")
        {
            Console.WriteLine("继续输入");
        }
    }

    public static void Testpallral2()
    {
        ParallelLoopResult result =
              Parallel.For(0, 100,async(int i, ParallelLoopState pls) =>
              {
                  Console.WriteLine(DateTime.Now.ToLongTimeString() + "{0}, task: {1}, thread: {2}", i,
                  Task.CurrentId, Thread.CurrentThread.ManagedThreadId);

                  await Task.Delay(10);
                    if (i > 5) pls.Break();
            Console.WriteLine(DateTime.Now.ToLongTimeString() + "after delay");

              }
        );

        while (Console.ReadLine() != "stop")
        {
            Console.WriteLine("继续输入");
        }
    }
    static void Main(string[] args)
    {
        //TestWhen();
        //Testpallral2();

    }

}

原文地址:https://blog.51cto.com/ggwhsd/2486148

时间: 2024-10-15 20:45:07

C#中的异步编程:await和async的相关文章

C#中的异步编程Async 和 Await

谈到C#中的异步编程,离不开Async和Await关键字 谈到异步编程,首先我们就要明白到底什么是异步编程. 平时我们的编程一般都是同步编程,所谓同步编程的意思,和我们平时说的同时做几件事情完全不同. 在计算机的世界里,同步编程的意思说 按照顺序来执行,或者说是 一个接着一个地有序的来执行, 比如目前我们在代码中有三件任务来执行,那么必须先执行完第1件,再执行第2件,接下来再执行第3件. 在这个过程中,第1件没有完成,你是没法开始做第2件事情的,必须等待. 比如一个人烧开水需要10分钟,5分钟找

Async in C# 5.0(C#中的异步编程Async) 蜗牛翻译之第一章

p { display: block; margin: 3px 0 0 0; } --> 写在前面 在学异步,有位园友推荐了<async in C#5.0>,没找到中文版,恰巧也想提高下英文,用我拙劣的英文翻译一些重要的部分,纯属娱乐,简单分享,保持学习,谨记谦虚. 如果你觉得这件事儿没意义翻译的又差,尽情的踩吧.如果你觉得值得鼓励,感谢留下你的赞,祝各位爱技术的园友在今后每一次应该猛烈突破的时候,不选择知难而退.在每一次应该独立思考的时候,不选择随波逐流,应该全力以赴的时候,不选择尽力

.Net中的异步编程

.Net中的异步编程? .net中实现异步有两种方式:第一种是多线程的方式,第二种是使用异步函数,其实在异步函数中使用的还是多线程的技术. 异步编程中比较关注也比较重要的技术点在于:1.当异步线程在工作完成时如何通知调用线程:2.当异步线程出现异常的时候该如何处理: 3.异步线程工作的进度如何实时的通知调用线程:4.如何在调用线程中取消正在工作的异步线程,并进行回滚操作. 虽然在.net中提供了众多的异步编程模式,但是推荐最好使用Task类,因为Task类使用线程池中的任务线程,又由线程池管理,

promise 的基本概念 和如何解决js中的异步编程问题 对 promis 的 then all ctch 的分析 和 await async 的理解

* promise承诺 * 解决js中异步编程的问题 * * 异步-同步 * 阻塞-无阻塞 * * 同步和异步的区别? 异步;同步 指的是被请求者 解析:被请求者(该事情的处理者)在处理完事情的时候的通知机制. 异步:当事情处理完成后被请求者会发信息通知请求者该事情处理完成.在这期间被请求者可以选择是继续等待命令请求完成还是去做其他事等待被请求者返回. 同步:当事情处理完成后被请求者不会告知请求者,等到请求者发来询问是才会告知 阻塞:非阻塞 指的是请求者 阻塞:针对请求者来说的,委托其他人处理一

[C#]剖析异步编程语法糖: async和await

一.难以被接受的async 自从C#5.0,语法糖大家庭又加入了两位新成员: async和await. 然而从我知道这两个家伙之后的很长一段时间,我甚至都没搞明白应该怎么使用它们,这种全新的异步编程模式对于习惯了传统模式的人来说实在是有些难以接受,不难想象有多少人仍然在使用手工回调委托的方式来进行异步编程.C#中的语法糖非常多,从自动属性到lock.using,感觉都很好理解很容易就接受了,为什么偏偏async和await就这么让人又爱又恨呢? 我想,不是因为它不好用(相反,理解了它们之后是非常

C#基础系列——异步编程初探:async和await

前言:前面有篇从应用层面上面介绍了下多线程的几种用法,有博友就说到了async, await等新语法.确实,没有异步的多线程是单调的.乏味的,async和await是出现在C#5.0之后,它的出现给了异步并行变成带来了很大的方便.异步编程涉及到的东西还是比较多,本篇还是先介绍下async和await的原理及简单实现. C#基础系列目录: C#基础系列——Linq to Xml读写xml C#基础系列——扩展方法的使用 C#基础系列——序列化效率比拼 C#基础系列——反射笔记 C#基础系列——At

全面解析C#中的异步编程

当我们处理一些长线的调用时,经常会导致界面停止响应或者IIS线程占用过多等问题,这个时候我们需要更多的是用异步编程来修正这些问题,但是通常都是说起来容易做起来难,诚然异步编程相对于同步编程来说,它是一种完全不同的编程思想,对于习惯了同步编程的开发者来说,在开发过程中难度更大,可控性不强是它的特点. 在.NET Framework5.0种,微软为我们系统了新的语言特性,让我们使用异步编程就像使用同步编程一样相近和简单,本文中将会解释以前版本的Framework中基于回调道德异步编程模型的一些限制以

.NET中的异步编程——动机和单元测试

背景 自.NET 4.5发布以来已经有很长一段时间了.留在了我们的记忆里,其发布在2012年8月15日.是的,六年前.感觉老了吗?好吧,我不打算让你做出改变,而是提醒你一些.NET发布的亮点.此版本带来的主要功能之一是使用async / await方法进行异步编程.基本上,微软的团队通过保持类似于同步代码的逻辑结构,使编译器完成开发人员过去经常做的工作. 你看,在那个时候,Windows Phone仍然是一件事情,为这些平台开发应用程序有一定的局限性.主要原因是Windows Phone与桌面应

ES6 异步编程解决方案 之 Async

一.async 函数的基本用法 async 函数返回一个 Promise 对象,可以使用 then .catch 方法 添加回调函数 async 函数执行时,一旦遇到 await 就会先返回,等到异步操作完成,再接着执行函数体内后面的语句 [异步函数 同步执行] async 函数有很多种形式: // 函数声明 async function foo() {} // 函数表达式 const foo = async function () {}; // 箭头函数 const foo = async (