首页 > 编程语言 >[个人笔记][C#]异步编程

[个人笔记][C#]异步编程

时间:2023-09-06 17:00:46浏览次数:57  
标签:异步 task C# 编程 多线程 任务 线程 执行

多线程的一点基础知识

  • 单核的性能逐渐逼近工业能力上限,开始通过多核来提高性能
  • 多线程逻辑很难写
  • 通过System.Diagnostics.Process访问进程
  • 被调用操作的执行和完成独立于调用它的控制流
  • 从IO受限的阻塞线程切换到就绪线程,提高处理器利用率,防止处理器闲置
  • 上下文切换会把寄存器和栈上的内容从CPU保存到内存,然后加载新线程的执行环境,上下文切换可能会导致上一个线程的CPU缓存被替换掉,造成更多的cache miss
  • 线程太多会导致上下文切换的开销比例显著提高,影响性能
  • 并发不会提高处理器受限的任务的性能,并发主要的作用是减少阻塞
  • 并行可以显著提高处理器受限的任务的性能
  • += 和 -=不是原子性操作
  • 竞态条件就是两个控制点以无法预测且不一致的速度竞争代码的执行
  • 竞态条件会造成不确定性且难以重现
  • 保证多线程代码的品质主要依赖长期的压力测试、代码分析共计和专家的code review
  • 处理器同步缓存的时机也可能会造成竞态条件,两个不同的线程读取同一块内存,可能会因为缓存同步时机的问题,获取到不同的结果(?这也太逆天了吧)
  • 操作系统保证同时只有一个线程可以获得锁执行代码,并保证遇到锁的时候处理器的缓存会正确同步
  • 锁是有性能开销的,而且可能会出现死锁
  • 大部分操作都不是原子性的,不要假设一个操作是原子性的
  • 避免所有竞态条件
  • 线程池避免了创建和销毁线程的巨大开销,同时可以避免创建过多线程,防止线程上下文切换的开销过大影响性能
  • 锁防止两个不同的线程同时访问数据
  • 只要有需要长时间运行的方法,就可能需要多线程编程
  • 每个线程在windows上的栈空间是1MB

TPL的简单使用

  • TPL创建一个Task,任务调度器从线程池请求一个工作线程进行执行,线程池可能会在当前任务结束后再运行新任务(不分配新线程),也可能重用一个线程池线程去执行任务,或者创建一个全新线程
  • Task代表异步工作的对象,委托是同步的,任务是异步的,委托封装的代码永远都是同步执行的,执行时当前线程的控制点立刻转移到委托内部,执行完成之后才会返回调用点,而任务启动后会立即返回到调用者,通常在另一个线程上异步执行
  • 常见的获取结果的方式:轮询、阻塞等待
  • IsCompleted非正常结束也会为true
  • CurrentId是任务的唯一标识ID
  • 通过延续将多个任务合并到一起,合并成较大的任务
  • 先驱任务完成时,延续任务自动开始
  • 同一个先驱的两个延续任务异步执行
  • 创建延续:
var taskA = Task.Run(() => { Console.WriteLine("Starting..."); })
    .ContinueWith(task => { Console.WriteLine("Continuing A..."); });
var taskB = taskA.ContinueWith(task => { Console.WriteLine("Continuing B..."); });
var taskC = taskA.ContinueWith(task => { Console.WriteLine("Continuing C..."); });
Task.WaitAll(taskB, taskC);
Console.WriteLine("Finished");
  • 实参task是延续task的先驱task,延续需要访问先驱的执行状态的
  • TaskContinuationOptions
    image
    image
  • 可以组合延续和flag,为一个任务的执行设定多个执行分支
  • 一个任务的几个延续互斥时,某一个延续开始执行后,任务调度器会自动取消另外几个互斥的延续,取消的任务的状态是Canceled,在Cancel的任务上调用Wait会抛出一个异常,因为被取消的任务永远不会执行,永远也而等不到
  • 可以用Task.WaitAny() 结合AggregateException(Aggregate是聚合的意思,这个异常可以理解为一个异常的集合)来处理所有分支延续
  • 不能用try包装Start来捕捉异常,因为Start会立即返回
  • 任何线程上的未处理异常都被视为严重错误,造成应用程序panic,所有线程上的异常都必须被捕捉
  • 任务调度器会有一个处理程序捕获所有的异常,防止CLR自动终止进程

标签:异步,task,C#,编程,多线程,任务,线程,执行
From: https://www.cnblogs.com/m1ds/p/17682669.html

相关文章

  • 视频集中存储/云存储/磁盘阵列EasyCVR平台分组批量绑定/取消设备功能详解
    安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台视频能力丰富灵活,可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等,以及支持厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等。视频汇聚融合管理平台EasyCVR既具备传统安防视频监控的能力,也具备接入AI智能分......
  • C#: 将可空的对象传给非空类型参数
    解决方案使用.Value属性获取可空Guid的实际值:如果你确定可空的Guid对象中包含了值(即非null),可以使用.Value属性来获取实际的Guid值。请确保在使用之前进行检查,以避免null引用异常。Guid?nullableGuid=GetNullableGuid();//假设你有一个可空的Guidif(nul......
  • Kuberners 强制删除pod 强制删除Terminating的NAMESPACE 强制删除ns
    强制删除NAMESPACE[root@k8s-master1~]#catdelete.sh#!/bin/bashset-eopipefaildie(){echo"$*"1>&2;exit1;}need(){which"$1"&>/dev/null||die"Binary'$1'ismissingbutrequired"......
  • 使用Nodejs的addon导入cpp生成的dll时出现的问题记录
    在使用Nodejs的addon导入自己编写的cpp的dll时出现的一系列问题记录标签:__declspec、Napi、LoadLibraryA、GetLastError、dumpbin/exports。正常创建一个使用Napi的nodejsaddon项目(网上都有,在这里不赘述),主要代码如下:#include<napi.h>#include<iostream>#include<atlst......
  • MindSponge分子动力学模拟——Constraint约束
    技术背景在前面的几篇博客中,我们已经介绍了MindSponge的基本使用方法,比如定义一个分子系统、计算分子的单点能以及迭代器的使用等。有了这些基础的教程,用户以及可以执行一些比较简单的模拟任务,比如可以跑一个能量极小化,或者是NVT过程。当我们去执行一个模拟任务时,比较关键的一个......
  • Oracle VM VirtualBox Ubuntu设置共享文件夹
    1、在windows系统中创建文件夹创建的这个文件夹最好选择在内存空间较大的磁盘中。否则会引起内存不足的困扰。在E盘中创建名为winshare的文件夹。2、设置共享文件夹打开OracleVMVirtualBox,点击设置。点击“共享文件夹”。点击加号。随后在共享文件夹路径中选择第一步......
  • vxe-table 的 setActiveRow() 无效
    问题vxe-table的setActiveRow(row)方法无效。解决检查之后发现,vxe-column上忘记写:edit-render="{}。因为#edit="{row}"插槽必须要写:edit-render="{}......
  • Tomcat7+ 弱口令 && 后台getshell漏洞
    Tomcat7+弱口令&&后台getshell漏洞环境说明Tomcat支持后台部署war文件,可以直接将webshell部署到web目录下。其中,欲访问后台,需要对应用户有相应权限。Tomcat7+权限分为:manger(后台管理)manger-gui拥有html页面权限manger-status拥有查看status的权限mager-jmx拥有jmx权限......
  • 基于高性能Cortex®-M33内核STM32H562RIV6、STM32H562RIT6、STM32H562RGV6 32-bit ARM
    简介STM32H562xx器件是基于高性能ARM®Cortex®-M3332位RISC内核的高性能微控制器系列(STM32H5系列)。它们的工作频率高达250MHz。Cortex®-M33内核具有单精度浮点单元(FPU)、支持所有ARM®单精度数据处理指令和所有数据类型。该系列微控制器具有1至2MB的Flash存储器、640KB的SRA......
  • 无涯教程-JavaScript - SECOND函数
    描述SECOND函数返回时间值的秒数。第二个数字以0(零)到59之间的整数形式给出。语法SECOND(serial_number)争论Argument描述Required/OptionalSerial_number您想找到包含秒数的时间。时间可以输入为-引号内的文本字符串(如"6:45PM")十进制数(如0.78125,代表......