C#异步编程之async/await

Async函数:await后的代码段由哪个线程执行? 阅读本篇文章前需要C#多线程基础、Async函数基础、SynchronizationContext基础 默认情况 以下是测试代码: static void Main(string[] args) { Test0(); Console.Read(); } stat... 阅读详情
  1. 通过async/await这两个关键字编写出来的代码,代码长(zhang)的像同步编程,但实际上是异步编程。也就是说,async/await能够以同步编程的形式实现异步编程。
  2. async/await是C#5.0引入的。
  3. 关键字async用在方法定义前面,关键字await只能用在async标记的方法中。
  4. async修饰的方法的返回值类型只能是void或者Task或者Task<T>这三种类型,且方法的参数能用ref/out修饰。
  5. await异步等待的地方,await后面的代码和前面的代码执行的线程可能不一样(取决于await时任务是否完成)。

参考资料:

https://www.cnblogs.com/liqingwen/p/5831951.html#!comments

https://www.c-sharpcorner.com/article/async-and-await-in-c-sharp/

以下为本人调试时的代码:

代码1:

using System;
using System.Threading;
using System.Threading.Tasks;

namespace 简单用法
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " 主线程ThreadId = " + Thread.CurrentThread.ManagedThreadId);
            AsyncTest();

            Console.ReadLine();
        }

        static Task<int> Print()
        {
            var tcs = new TaskCompletionSource<int>();
            var thread = new Task(() =>
            {
                Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " 子线程Id = " + Thread.CurrentThread.ManagedThreadId);
                for (int i = 0; i < 3; i++)
                {
                    Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " =====等待===== " + i);
                    Thread.Sleep(1000);
                }

                tcs.SetResult(99);
            });

            thread.Start();

            return tcs.Task;
        }

        async static void AsyncTest()
        {
            Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " *****Start***** ThreadId = " + Thread.CurrentThread.ManagedThreadId);

            Task<int> taskA = Print();

            Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " *****Middle***** ThreadId = " + Thread.CurrentThread.ManagedThreadId);

            await taskA;//await后面的代码和前面的代码执行的而线程可能不一样(这个应该是涉及“出让执行权”)

            Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "*****End***** ThreadId = " + Thread.CurrentThread.ManagedThreadId);
        }
    }
}

运行结果:

代码2:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

//In this example,we are going to take two methods,
//which are not dependent on each other.
namespace 简单用法2
{
    class Program
    {
        static void Main(string[] args)
        {
            Method1();
            Method2();
            Console.ReadLine();
        }

        public static async Task Method1()
        {
            await Task.Run(() =>
            {
                for (int i = 0; i < 100; i++)
                {
                    Console.WriteLine(" Method 1 ");
                    Thread.Sleep(100);
                }
            });
        }

        public static void Method2()
        {
            for (int i = 0; i < 25; i++)
            {
                Console.WriteLine(" Method 2 ");
                Thread.Sleep(500);
            }
        }
    }
}

运行结果:

代码3:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

//In this example,Method1 is retirning total length as an integer value and we are passing a parameter
//as a length in a Method3,Which is coming from Method1.
namespace 简单用法3
{
    class Program
    {
        static void Main(string[] args)
        {
            callMethod();
            Console.ReadLine();
        }

        public static async void callMethod()
        {
            Task<int> task = Method1();
            Method2();
            int count = await task;
            Method3(count);
        }

        public static async Task<int> Method1()
        {
            int count = 0;
            await Task.Run(() =>
            {
                for (int i = 0; i < 100; i++)
                {
                    Console.WriteLine(" Method 1 ");
                    count++;
                    Thread.Sleep(100);
                }
            });
            return count;
        }

        public static void Method2()
        {
            for (int i = 0; i < 25; i++)
            {
                Console.WriteLine(" Method 2 ");
                Thread.Sleep(200);
            }
        }

        public static void Method3(int count)
        {
            Console.WriteLine("Total count is " + count);
        }
    }
}

运行结果:

代码4:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

//In this example,we are going to read all the character from a
//large text file asynchronously and get the total length of all the characters.
namespace 简单用法4
{
    class Program
    {
        static void Main(string[] args)
        {
            Task task = new Task(CallMethod);
            task.Start();
            task.Wait();
            Console.ReadLine();
        }

        static async void CallMethod()
        {
            string filePath = @"C:\Io.dos";
            Task<int> task = ReadFile(filePath);

            Console.WriteLine(" other work 1");
            Console.WriteLine(" other work 2");
            Console.WriteLine(" other work 3");

            int length = await task;
            Console.WriteLine(" Total length = " + length);

            Console.WriteLine(" After work 1");
            Console.WriteLine(" After work 2");
        }

        static async Task<int> ReadFile(string file)
        {
            int length = 0;
            Console.WriteLine(" File reading is starting ");
            using (StreamReader reader = new StreamReader(file))
            {
                //Reads all characters from the current position to the end
                //of the stream asynchronously and returns them as one string.
                string s = await reader.ReadToEndAsync();
                length = s.Length;
            }
            Console.WriteLine(" File reading is completed ");
            return length;
        }
    }
}

运行结果:

C#异步编程 async/await C#的async/await是基于 Task 的语法糖,本质上不引入新的多线程机制,而是简化异步编程模型,让异步代码像同步代码一样简洁易读。async用于修饰方法,await用于等待异步操作,需配合使用。适用于I/O密集型任务(如网络请求、文件操作)和UI交互场景,不适合CPU密集型计算 阅读详情

相关推荐

C# 异步编程async/await

异步这个概念在不同语境下有不同的解释,比如在一个单核CPU里开启两个线程执行两个函数,通常认为这种调用是异步的,但对于CPU来说它是单核不可能同时运行两个函数,不过是由系统调度在不同的时间分片中执行。一般来说,如果两个工作能同时进行,就认为是异步的。在编程中,它通常代表函数的调用可以在不执行完的情况下返回,必要时在完成时回调。有一个概念常常被混淆,多线程和异步。

xxxzzzqqq_的博客 1489

C# async/await异步编程

C# async/await异步编程前言异步方法的结构调用异步方法异步方法本体耗时函数`async`/`await`异步函数的原理示例代码的执行流程带返回值的异步函数死锁这样没省多少事啊?参考: 前言 Talk is cheap, Show you the code first! 先上代码: private void button1_Click(object sender, EventArgs e) { Console.WriteLine("111 balabala. My Thread ID is

天富儿的博客 1649

C# 异步编程详解(Task,async/await)

同步和异步主要用于修饰方法。当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法;当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务,调用者不用等待该方法执行完毕,我们称这个方法为异步方法。异步的好处在于非阻塞(调用线程不会暂停执行去等待子线程完成),因此我们把一些不需要立即使用结果、较耗时的任务设为异步执行,可以提高程序的运行效率。

luxingyu329的博客 4152

[C#]从两个例子理解async/await

1 例子1 输出的结果为: 可以看出执行的结果为:A——D——B——C——E. 我们再看下一个例子(注意,我们把代码中D和E的位置交换) 2 例子2 结果: 结果为:A——B——C——E——D 3 理解 Async方式,使用Async标记Test为异步方法,用Await标记Task表示方法内需要耗时的操作。主线程碰到a...

李正浩的博客 1333

c#异步编程(async/await)

c# sync/await

积累点滴,保持自我 1168

C#异步编程实战:Task与async/await的高效应用指南

本文深入探讨C#异步编程的核心机制,重点解析Task与async/await的高效应用。通过实战示例,详细讲解Task的创建、等待、延续、取消与异常处理,以及async/await如何简化异步代码编写。文章还提供了避免死锁、优化性能的实战避坑指南,帮助开发者提升应用程序的响应速度与资源利用率。

weixin_29302047的博客 617

C#多线程和异步编程——Task和async/await详解

目录 一、什么是异步 二、Task介绍 1 Task创建和运行 2 Task的阻塞方法(Wait/WaitAll/WaitAny) 三、异步方法(async/await) 一、什么是异步   同步和异步主要用于修饰方法。当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法;当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务,调用者不用等待该方法执行完毕,我们称这个方法为异步方法。   异步的好处在于非阻塞(调用线程不会暂停执行去等待子线程.

xujianjun229的博客 3052

C#异步编程模型:Task并行与async/await深入剖析

C#提供了基于Task并行库(TPL)的Task异步模型,以及async/await语法糖,极大地简化了异步编程的复杂性。通过本篇深入剖析,您应已全面理解C#中的Task并行与async/await异步编程模型,掌握了如何利用这些机制编写高效、非阻塞性的异步代码。结合文中提供的代码示例与注释,您可以轻松地将异步编程应用于实际项目中,并根据需要进行更深入的学习与优化。以上各部分已包含丰富的代码示例,并附有详细注释,阐述了Task并行、async/await关键字的使用以及异步编程的最佳实践。

java专栏 1523

C# async/await 异步编程

/ 异步操作// 模拟耗时操作C# 中的异步编程通过async和await关键字实现,能够显著提高程序的响应性和性能。它特别适用于 I/O 密集型操作、UI 应用程序和 Web 应用程序等场景。通过合理使用异步编程,可以编写出高效、简洁且易于维护的代码。

malaopang的博客 1233

电源芯片TPS54560典型应用电路及设计详解

TPS54560 是一款配有集成型高侧 MOSFET 的 60V、5A DC-DC转换器,输入电压范围7-60V,输出电压可通过外部反馈电阻设置成略低于输入电压的任意值。**所以,**R5=31.25KΩ、R6:10KΩ(常用值)时,即可设置输出电压为 3.3V。**所以,**R5=140KΩ、R6:10KΩ(常用值)时,即可设置输出电压为12V。设计 TPS54560 的输出电压时,主要通过外部反馈电阻网络来设置输出电压。因此,输出 3.3V ,输入电压24V时推荐的电感值为 8µH 至 10µH。

weixin_42306872的博客 1万+

无源低通滤波器

无源RC滤波器“滤除”不需要的信号,因为它们分离并允许仅通过其频率的正弦输入信号,最简单的是无源低通滤波器网络。在低频应用(高达100kHz)中,无源滤波器通常使用简单的RC(电阻-电容)网络构建,而高频滤波器(高于100kHz)通常由RLC(电阻-电感-电容)元件制成。无源滤波器由电阻器、电容器和电感器等无源元件组成,没有放大元件(晶体管、运算放大器等),因此没有信号增益,因此它们的输出电平始终小于输入。滤波器是根据它们允许通过它们的信号的频率范围来命名的,同时阻挡或“衰减”其余部分。

weixin_44448586的博客 1万+

C#中的async/await彻底改变异步编程模式

随着云原生和微服务架构的普及,高效处理并发和异步操作的能力将变得愈加重要,而async/await作为C#异步编程的基石,必将在这一过程中发挥关键作用。首先,异步方法命名约定建议方法名以Async后缀结尾,这清晰表明了方法的异步特性,方便开发者识别和使用。开发者可以使用熟悉的try/catch块来捕获异步操作中的异常,就像处理同步代码一样自然,这大大提高了异步代码的可靠性。这一语法糖彻底改变了开发者编写异步代码的方式,使得异步代码在结构上和同步代码几乎一样简洁明了,大大降低了异步编程的理解和实现门槛。

Steve_ke的博客 926

【QGIS】利用“创建网格”功能实现区域等距分割与坐标转换实战

本文详细介绍了如何在QGIS中使用“创建网格”工具实现区域等距分割。通过实战演示,将北京市行政区划切割为150米正方形网格,并重点讲解了关键步骤:选择投影坐标系EPSG:3857以确保网格尺寸精确,以及将结果转换为常用的WGS84经纬度坐标。文章还涵盖了进阶技巧与常见问题解决方案,帮助用户高效完成空间网格化分析任务。

weixin_29232507的博客 95

探索C#异步编程从Task到async/await的全面解析

Task作为.NET 4.0引入的核心异步编程模型,代表了异步操作的抽象概念。通过Task.Run方法,可以轻松将同步代码转换为异步执行,同时Task.Status属性提供了对任务状态的实时监控能力,包括Created、WaitingForActivation、Running和Completed等状态值。异常处理方面,应当使用try-catch块包装await表达式,因为异步方法的异常会存储在返回的Task对象中。async/await关键字的引入是C# 5.0的重大革新,它极大简化了异步编程的复杂性。

技术派做新零售创业 744

【3d打印】基于Klipper的3d打印远程上位机系统(Qt),klipper源码,通信解析,打印参数设置

基于Klipper的3d打印远程上位机系统(Qt),klipper源码,通信解析,打印参数设置(启庞Kp3s V1)

共享IT之美,共创机器未来 3192

【功能安全】【AutoSAR】程序流监控机制

目录 一、程序流执行的常见故障 二、程序流的监控机制 1、监控功能的实现 2、三种监督机制 a、生命监测机制 b、截止时间监测机制 c、逻辑程序流监测机制 一、程序流执行的常见故障 与程序流相关的故障,在ISO26262中第六章附录D中定义如下: — 执行阻塞; — 死锁; — 活锁; — 执行时间的不正确分配; — 软件要素间的不正确同步。 二、程序流的监控机制 1、监控功能的实现 AutoSAR中对程序流的监控功能的实现主要有“看门狗”栈(Watchdog Stack).

专注汽车软件开发、AutoSAR、车载以太网、SOA、EE架构。 4518

C# 异步编程:从 async/await 到 Task 并行库的全面解析

本文全面介绍了C#异步编程的核心技术,包括async/await关键字和Task并行库。通过对比同步编程的局限性,阐述了异步编程在处理I/O密集型和CPU密集型任务时的优势。文章详细解析了async/await的使用方法,展示了Task类及其泛型版本Task<T>的基本用法,并介绍了并行任务处理的WhenAll和WhenAny方法。最后结合文件读写、网络请求等实际应用场景,说明了异步编程如何提升程序性能和响应速度。全文为开发者提供了从基础到实践的异步编程指南。

葡萄城技术团队博客 1229

Oracle EBS 寄销/VMI(1)-->基础设置

名词解释:     BPA:一揽子采购协议     BPR:一揽子发放     SR:来源补充规则     ASL:合格供应商列表     VMI: 供应商管理库存     寄售(Consignment)是把货物放在客户那里,客户要用的时候才付款的库存,一般是指卖方把

陈显平的专栏-Oracle EBS 1万+

深入浅出 C# 异步编程:掌握 async/await 的最佳实践

在同步编程中,执行的每个任务都会阻塞当前线程,直到任务完成。而在异步编程中,任务在等待时不会阻塞线程,其他任务可以继续执行,直到被等待的任务完成。这种非阻塞的执行方式,使得应用程序能够在处理 I/O 密集型操作时保持响应性,从而提高用户体验和系统性能。Console.WriteLine("异步任务开始");// 调用异步方法Console.WriteLine("异步任务完成");// 使用 async 关键字标记方法为异步方法Console.WriteLine("开始执行异步任务...")

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 2798

【国产MCU】-CH32V307-通用定时器(GPTM)-输入捕获模式测量脉冲

CH32V307的通用定时器模块包含一个16 位可自动重装的定时器(TIM2、TIM3、TIM4和TIM5),用于测量脉冲宽度或者产生特定频率的脉冲、PWM波等。可用于自动化控制、电源等领域。 输入捕获是通用定时器功能之一,一般用于测量频率和测量脉冲宽度。本文将详细介绍如何通用定时器的输入捕获功能。

视觉与物联智能 2814

vue3 - 最新详细实现高德地图绘制动态热力图详细教程,在某区域或城市地图上做“热力图层“展示人流量、旅游人口密度、热量图、全国地区地理热力图,利用颜色的深浅表示密度或强度等场景(详细示例代码教程)

vue3,nuxt3,高德地图,热力图,绘制热力图层,人流量,vue3使用高德地图实现某个区域热力图,vue3高德地图api加载热力图及关闭,接收热力图数据并渲染热力图,关掉热力图,Vue使用高德API制作热力图,热力图加载不出来,电子围栏围住热力图,vue3中使用高德地图渲染热力图组件,高德地图使用热力图详细教程,报错,卡顿,出不来怎么办,无法关闭,怎么解决这个问题,出错,城市名称,城市某个街道,城区,省份,市区,县城,乡镇,村,各省份的热力图,交通流量,人口流量,密度,旅游出行,人口数量,颜色介绍,深浅

✅ 精选推荐文章 5205

探索C#异步编程从Task到async/await的实践指南

然而,尽管TPL功能强大,使用回调式的延续仍然可能导致代码嵌套过深,难以维护,这便是async/await语法糖所要解决的核心问题。await关键字则用于挂起当前方法的执行,直到其等待的Task完成,同时将控制权返回给调用方,避免了线程的阻塞。这种机制确保了异步操作的高效性,同时极大简化了开发者需要编写的代码量,将复杂性完全隐藏在编译器生成的代码中。更重要的是,异步方法返回的Task会将异常封装在AggregateException中,或者通过await自动解包,使得调用方能够以自然的方式处理异常。

huangxiaobeng的博客 1224

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

C# 异步编程和 async/await

异步编程是一种在程序执行过程中,允许执行其他任务而不阻塞当前任务的编程模式。这对于处理需要等待的操作(例如文件 I/O、网络请求)尤为重要。

Lsss123aa的博客 656

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

C# 异步编程Async/Await 原理及使用详解

async和await使得异步编程更加直观和易于维护。异步方法通常返回Task或。使用await可以暂停方法的执行,直到异步操作完成。异常处理可以通过try-catch块来实现。通过使用async和await,你可以编写出高效且易于理解的异步代码,提升应用程序的响应性和性能。

yuanpan的专栏 1062

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

深入理解C# 异步编程与async/await机制

异步编程能够显著提升应用程序的性能和响应能力。在 C# 中,async 和 await 是实现异步编程的基础工具,通过它们,我们可以轻松地将耗时任务放在后台执行,而不阻塞主线程。掌握异步编程的基本原则和常见陷阱,可以帮助开发者构建更加高效、健壮的应用程序。

lichangjun2017的博客 1861
上一篇: C#中的Task
下一篇: C#中的TaskCompletionSource<TResult>
coder_chenwei
博客等级 码龄11年 14粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值