ToB企服应用市场:ToB评测及商务社交产业平台

标题: C#异步编程 [打印本页]

作者: 嚴華    时间: 2022-9-21 02:18
标题: C#异步编程
受众

.Net c#开发人员
概念

免责声明:计算机科学很多概念都没有类似数学一样严谨的定义,以下概念为个人理解
程序(Program)

静态模板
进程(Process)

程序的实例,一个程序可以有多个进程
线程(Thread)

一个进程可以有多个线程,CPU调度分配最小单位
协程(Coroutine)

一个线程有多个协程,用户控制
同步(Synchronous)

执行一个任务只有完成后,才会执行下一个任务
异步(Asynchronous)

执行一个任务不管有没有完成,就开始执行下一个任务,如果任务没有结果则任务完成后会通过状态、通知和回调告知完成。目的是为了提高资源利用率,减少线程等待,而不是为了提高性能,有时使用异步反而性能会降低,但因为减少了等待所以单位时间内做的任务更多了,从而导致性能提升了,所以是用CPU资源换时间
同步vs异步

区别在于任务之间是否会等待完成才开始执行,同步有明确的调用链顺序。异步可以类比计算机休眠(Sleep)然后再启动,同步可以类比计算机睡眠(Shut Down)
异步和多线程

多线程是实现异步的其中一种方式,但是异步本身不一定会创建线程,而是任务完成以后系统找寻同步上下文,如果存在则使用之前的同步上下文对应的线程继续执行后续语句,否则自动创建线程执行后续语句;单线程通过事件通知也能做到异步:某个线程去读取某个文件Bytes,CPU告诉磁盘去读取该文件,该线程就返回去做其它任务了,等磁盘通过DMA读取完成该文件完成后通过事件通知该线程,该线程会从内存中拿到文件的Bytes
阻塞(Blocking)

线程挂起 等待某个操作执行完成,期间CPU不会分配时间片给该线程,该线程无法执行其它代码
非阻塞(Non Blocking)

就算某个方法没执行完,线程也会返回
阻塞vs非阻塞

调用者是否一直等待结果,期间不执行其它代码
同步异步 vs 阻塞非阻塞

同步异步关注如何得到结果以及得到结果后如何告知调用者完成,阻塞非阻塞关注如何等待结果,是线程等着完成还是先做其它事情等完成的后通知、回调或者轮询状态。同步和异步与阻塞和非阻塞没有任何关系,所以可以存在4种情况:同步阻塞、同步非阻塞、异步阻塞和异步非阻塞。
同步阻塞

某个线程执行一个同步方法,方法返回结果前, 后续代码不会执行,且该线程一直挂起等待结果,期间不会复用执行其它代码
  1. public static string SyncBlocking()
  2. {
  3.     return SyncDownload();// 线程执行同步方法,并等待它完成期间不做其它任何事情
  4. }
  5. public static string SyncDownload()
  6. {
  7.     var webClient = new WebClient();
  8.     return webClient.DownloadString("https://www.baidu.com");
  9. }
复制代码
同步非阻塞

某个线程执行一个同步方法,方法没有得到结果前不会返回,该线程会回线程池,期间可能被复用执行其它代码
  1. public static async Task<string> SyncNonBlocking()
  2. {
  3.     // 此处会从线程池中选择一个新线程B执行SyncMethod,如果要具体控制使用哪个线程或者如何排队需要使用Task.Factory.StartNew
  4.     var task = Task.Run(() => SyncDownload());
  5.     var result = await task;// 原线程A执行到此然后马上返回,不等待同步方法完成就返回,这样可以去做其它事情
  6.     return result;
  7. }
  8. public static string SyncDownload()
  9. {
  10.     var webClient = new WebClient();
  11.     return webClient.DownloadString("https://www.baidu.com");
  12. }
复制代码
异步阻塞

某个线程执行一个异步方法,方法立即返回,后续代码会被执行,直至执行到需要返回结果的代码,该线程挂起等待结果,期间不会复用执行其它代码
  1. public static string AsyncBlocking()
  2. {
  3.     var task = AsyncDownload();
  4.     return task.Result; //虽然是异步操作,但是线程呆呆的等它完成然后获取结果,期间不做其它事情
  5. }
  6. public static Task<string> AsyncDownload()
  7. {
  8.     var webClient = new WebClient();
  9.     return webClient.DownloadStringTaskAsync("https://www.baidu.com");
  10. }
复制代码
异步非阻塞

某个线程执行一个异步方法,方法立即返回,后续代码会被执行,直至执行到需要返回结果的代码,该线程会回线程池,期间可能被复用执行其它代码
  1. public static async Task<string> AsyncNonBlocking()
  2. {
  3.     var result = await AsyncDownload();// 线程执行到此然后马上返回,可以去做其它事情
  4.     return result;//完成后会获取结果并继续执行后面的代码
  5. }
  6. public static Task<string> AsyncDownload()
  7. {
  8.     var webClient = new WebClient();
  9.     return webClient.DownloadStringTaskAsync("https://www.baidu.com");
  10. }
复制代码
串行

系统顺序执行多个任务,前一个任务完成后才开始执行下一个任务。同一时刻,只可以有一个任务是开始状态或执行状态
例子:1个处理窗口 1个任务队伍 任务处理完成 移除
[table][tr]时间片1时间片2时间片3时间片4时间片5[/tr][tr][td]
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4