C#高级 02异步编程

基础知识

1.什么是异步任务

  • 包含了异步任务的各种状态的一个引用类型
    1)正在运行、完成、结果、报错等
    2)另有ValueTask值类型版本
  • 对于异步任务的抽象
    1)开启异步任务后,当前线程并不会阻塞,而是可以去做其他事情
    2)异步任务(默认)会借助线程池在其他线程上运行
    3)获取结果后回到之前的状态
  • 任务结果
    1)返回值为Task的方法表示异步任务没有返回值
    2)返回值为Task则表示有类型为T的返回值

2.异步方法(async Task)

  • 将方法标记async后,可以在方法中使用await关键字
  • await关键字会等待异步任务,并获得结果
  • async+await会将方法包装成状态机,await类似于检查点(MoveNext方法会被底层调用,从而切换状态)
  • async Task
  • async void
  • 异步编程具有传染性

3.不阻塞

  • await会展示释放当前线程,使得该线程可以执行其他工作,而不必阻塞线程直到异步操作完成
  • 不要在异步方法里面用任何方式阻塞当前线程
  • 常见阻塞情况
    1)Task.Wait() & Task.Result()如果任务没有完成,则会阻塞当前线程,容易导致死锁
    2)Task.Delay() 是一个异步任务,会立刻释放当前线程
    3)Thread.Sleep() 会阻塞当前的线程,这与异步编程的理念不符
    4)IO等操作的同步方法
    5)其他繁重且耗时的任务

4.同步上下文

  • 一种管理和协调线程的机制,允许开发者将代码的执行切换到特定线程
  • WinForms 与 WPF 拥有同步上下文(UI线程),而控制台程序默认没有
  • ConfigureAwait(false)
    1)配置任务通过await方法结束后是否会到原来的线程,默认为true
    2)一般只有UI线程会采用这种策略
  • TaskScheduler
    1)控制Task的调度方式和运行线程
    1.1)线程池线程Default
    1.2)当前线程CurrentThread
    1.3)单线程上下文 STAThread
    1.4)长时间运行线程LongRunning
    2)优先级、上下文、执行状态等

5.一发即忘

  • 调用一个异步方法,但是并不使用await或阻塞的方式去等待它的结果
  • 无法观察任务状态(是否完成、是否报错等)

二.常见误区

1异步是否一定是多线程?

  • 异步编程不必需要多线程来实现(时间片轮转调度)
  • 比如可以在单个线程上使用异步I/O或事件驱动的编程模型(EAP)
  • 单线程异步:自己定好计时器,到时间之前先去做别的事
  • 多线程异步:将任务交给不同的线程,并由自己来进行指挥调度

2.异步方法一定要写成 async Task?

  • async关键字知识用来配合await使用,从而将方法包装成状态机
  • 本质上任然是Task,只不过提供了语法糖,并且函数体中可以直接return Task的泛型类型
  • 接口中无法声明async Task

3.await一定会切换同步上下文?

  • 在使用await关键字调用并等待一个异步任务时,异步方法不一定会立刻来到新的线程上
  • 如果 await 了一个已经完成的任务(包括Task.Delay(0)),会直接获得结果

4.异步编程可以取代多线程

  • 异步编程和多线程有一定关系,但是两者并不是可以完全相互代替的

5.Task.Result一定会阻塞当前线程?

  • 如果任务已经完成,那么Task.Result可以直接得到结果

6.开启的异步任务一定不会阻塞当前线程?

await关键字不一定会立刻释放当前线程,所以如果调用的异步方法中存在阻塞(如 Thread.Sleep(0)),那么依旧会阻塞当前线程上下文对应的线程

相关推荐
波力海苔夹心脆67516 小时前
C# 序列化与反序列化详解:System.Text.Json、Newtonsoft.Json、XmlSerializer 用法、特性选项与安全实践
经验分享·后端·c#·json·.net
小羊没烦恼!1 天前
在Scrum中实施敏捷建模
java·开发语言·windows·算法·c#
Lost of 程序猿1 天前
建造者模式实战:告别“十参数构造函数“的数据导出任务
后端·设计模式·c#·asp.net
mudtools1 天前
在.NET现有系统中快速集成飞书任务分配能力
后端·c#·.net
工具派1 天前
Word文档太大怎么拆分?段落结构与两种拆法的边界实测
开发语言·c#·word
潜龙95271 天前
需求文档一键变测试用例:手工用例智能生成平台
开发语言·c#
Lost of 程序猿1 天前
命令模式实战:把“下单后的动作“打包成可执行的任务
后端·设计模式·c#·asp.net·命令模式
淡海水1 天前
16-01-C#数据结构源码-附录A-术语表
unity·c#·游戏引擎·il2cpp
小羊没烦恼!1 天前
【译】利用Asp.net MVC处理文件的上传下载
开发语言·缓存·c#·word·powerpoint·.net
波力海苔夹心脆6751 天前
C# 海康威视摄像头二次开发入门:HCNetSDK 登录、实时预览、云台控制、录像与抓图(WinForms 实战)
开发语言·windows·经验分享·tcp/ip·c#