C#异步和多线程的理解

打印 上一主题 下一主题

主题 1788|帖子 1788|积分 5364

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
1. 异步编程(Asynchronous Programming)

异步编程是通过非阻塞方式实行使命,通常适用于I/O 麋集型使命,比方文件读写、网络哀求、数据库访问等。这类操作不必要占用大量 CPU 资源,而是等待外部资源(如网络或硬盘)响应。
在 C# 中,异步编程使用 async 和 await 关键字来实现。异步方法会返回 Task 或 Task<T>,调用 await 后,主线程可以继续实行其他代码,不会被阻塞。异步使命完成后,程序会回到 await 的位置继续实行。
异步代码示例

以下是一个使用异步编程的示例:
  1. using System;
  2. using System.Net.Http;
  3. using System.Threading.Tasks;
  4. class Program
  5. {
  6.     static async Task Main()
  7.     {
  8.         Console.WriteLine("Starting download...");
  9.         string content = await DownloadContentAsync("https://example.com");
  10.         Console.WriteLine("Download completed!");
  11.         Console.WriteLine($"Content length: {content.Length}");
  12.     }
  13.     static async Task<string> DownloadContentAsync(string url)
  14.     {
  15.         using HttpClient client = new HttpClient();
  16.         // 异步地开始下载内容
  17.         string content = await client.GetStringAsync(url);
  18.         return content;
  19.     }
  20. }
复制代码
在这个例子中,DownloadContentAsync 是一个异步方法。调用 await DownloadContentAsync(...) 后,Main 方法不会被阻塞,它会开释 CPU,等到下载完成后再继续实行。这种非阻塞模式适合 I/O 麋集型使命。
这里该怎么理解,为什么不会阻塞,举个实际业务的例子,就是微信付出的接口并不马上返回付出效果,这就是没有阻塞线程,线程继续做其他事情,付出效果通过回调接口关照;那么假如不是异步会是什么样的,那就是不停等待微信付出的接口响应,这个时候线程就被阻塞了。异步可以理解成回调,进一步说.Net程序向操作系统读取文件,访问网络,什么时候读到了文件,什么时候网络有了响应再回调给.Net程序,.Net程序再启用线程池的线程继续完成回调后的使命,这也是异步后线程id会改变的原因。
2. 多线程编程(Multithreading Programming)

多线程编程是通过在多个线程上并行实行使命,适用于CPU 麋集型使命,如复杂盘算、数据处置惩罚等。这类操作必要充实利用 CPU 的多焦点能力来同时处置惩罚多个使命。
在 C# 中,多线程编程可以通过 Thread、ThreadPool、Task 等类实现。与异步不同,多线程会创建多个线程来实行不同的使命,这样多个使命可以并发运行。
多线程代码示例

以下是一个使用多线程的示例:
  1. using System;
  2. using System.Threading;
  3. using System.Threading.Tasks;
  4. class Program
  5. {
  6.     static void Main()
  7.     {
  8.         Console.WriteLine("Starting CPU-intensive tasks...");
  9.         // 启动两个并行任务
  10.         Task task1 = Task.Run(() => PerformCpuIntensiveTask("Task 1"));
  11.         Task task2 = Task.Run(() => PerformCpuIntensiveTask("Task 2"));
  12.         // 等待任务完成
  13.         Task.WaitAll(task1, task2);
  14.         Console.WriteLine("All tasks completed.");
  15.     }
  16.     static void PerformCpuIntensiveTask(string taskName)
  17.     {
  18.         Console.WriteLine($"{taskName} started.");
  19.         for (int i = 0; i < 1000000000; i++)
  20.         {
  21.             // 模拟计算任务
  22.             double x = Math.Sqrt(i);
  23.         }
  24.         Console.WriteLine($"{taskName} completed.");
  25.     }
  26. }
复制代码
在这个例子中,Task.Run 会在 ThreadPool 中创建并启动新的线程来实行 PerformCpuIntensiveTask,这样 Task 1 和 Task 2 就可以并行实行,进步了 CPU 使用服从。
实在无论是时阻塞的耗时照旧复杂盘算的耗时,这两个都是耗时,但是这两个又有很大区别,阻塞的耗时可以通过回调,开释当火线程来解决阻塞的问题,但是复杂盘算的耗时核回调就没有关系了。举个具体点的例子,要盘算一个天文级别的数字,一个人要10天,但是你发现这些数子是可以拆开来分给不同的人盘算,末了把效果加起来就行了。这种环境下使用多线程处置惩罚盘算使命,然后把效果加起来,减少了耗时,同时也进步了cpu的使用率。
总结



  • 异步主要用于非阻塞 I/O 操作,让程序在等待 I/O 时开释资源,适合 I/O 麋集型使命。适用于串行使命,不提拔单次耗时,但是对整个程序来说可以提示吞吐量。
  • 多线程用于让多个使命并行实行,充实利用 CPU 焦点资源,适合 CPU 麋集型使命。之前的单次使命可以拆分给不同使命实行的话可以提拔耗时,通过消耗硬件资源实现并行或者并发提拔服从。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

傲渊山岳

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表