【C#】C#异步和多线程,Thread,Task和async/await关键字

[复制链接]
发表于 2025-11-9 17:50:08 | 显示全部楼层 |阅读模式

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

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

×
目次
一.多线程和异步的区别
1.多线程
2.异步编程
多线程和异步的区别
二.Thread,Task和async/await关键字的区别
1.Thread
2.Task
3.async/await
三.Thread,Task和async/await关键字的详细对比
1.Thread和Task的详细对比
2.Task 与 async/await 的共同使用
3. async/await 的现实应用场景
4.关键区别总结



   弁言:在 C# 编程中,多线程和异步编程都是用于进步应用步调性能和相应性的技能,但它们的用途和实现方式有所差异
  一.多线程和异步的区别

1.多线程

界说:


  • 多线程是指在一个应用步调中同时运行多个线程,每个线程都独立实行代码.这些线程大概在多个处理处罚器核心上并行运行,也大概在单个核心上通过期间片轮转方式运行
特性:


  • 并行实行:多个线程可以并行执使用命,进步 CPU 使用率,实用于 CPU 麋集型任务
  • 共享内存空间:同一进程中的线程共享内存空间,可以方便地共享数据,但也必要处理处罚同步题目
  • 线程管理:必要开辟者手动管理线程的创建,启动,同步和烧毁
使用场景:


  • 必要并行处理处罚多个 CPU 麋集型任务,以充实使用多核 CPU 的本领
  • 必要在背景实行复杂盘算,同时保持应用步调的相应性
2.异步编程

界说:


  • 异步编程是一种编程范式,答应步调在等候长时间运行的利用(如 I/O、网络哀求)完成时,不壅闭当火线程,从而进步应用步调的相应性和服从
特性:


  • 非壅闭:异步利用不会壅闭线程,当火线程可以继承实行其他任务
  • 变乱驱动:通过回调,变乱或任务的方式在利用完成时关照应用步调
  • 实用于 I/O 麋集型任务:特别是磁盘,网络等 I/O 利用,这些利用等候时间长,CPU 使用率低
使用场景:


  • 防止界面卡顿:在 GUI 应用步调中,防止长时间的利用壅闭 UI 线程,保持界面相应性
  • 服务器高并发:在服务器应用中,异步利用可以处理处罚大量并发 I/O 哀求,进步吞吐量
多线程和异步的区别

  1. // 多线程示例
  2. public void ThreadMethod()
  3. {
  4.     // 创建新线程
  5.     Thread thread = new Thread(() =>
  6.     {
  7.         // 这段代码在新线程上运行
  8.         DoSomeWork();
  9.     });
  10.     thread.Start();
  11. }
  12. // 异步示例
  13. public async Task AsyncMethod()
  14. {
  15.     // 不会创建新线程,而是在当前线程上异步执行
  16.     await Task.Run(() =>
  17.     {
  18.         DoSomeWork();
  19.     });
  20. }
复制代码


  • 目的差异:多线程重要用于并行实行 CPU 麋集型任务,异步编程重要用于非壅闭地实行 I/O 麋集型任务
  • 实现方式:多线程通过创建和管理线程实现并行,异步编程通过非壅闭的利用和回调机制实现,不肯定必要多线程
  • 资源使用:多线程大概会创建大量线程,占用体系资源;异步编程通常使用回调或任务,不必要额外的线程
    1. // 多线程示例 - CPU密集型计算
    2. public void ThreadExample()
    3. {
    4.     Thread calculateThread = new Thread(() =>
    5.     {
    6.         // 复杂计算
    7.         for (int i = 0; i < 1000000; i++)
    8.         {
    9.             // 进行大量计算
    10.         }
    11.     });
    12.     calculateThread.Start();
    13. }
    14. // 异步示例 - I/O操作
    15. public async Task AsyncExample()
    16. {
    17.     // 读取文件
    18.     string content = await File.ReadAllTextAsync("file.txt");
    19.     // 发送网络请求
    20.     var response = await httpClient.GetAsync("http://api.example.com");
    21. }
    复制代码

二.Thread,Task和async/await关键字的区别

1.Thread

界说:


  • System.Threading.Thread 类表现 .NET 中的一个线程,可以用来手动创建,控制和管理线程
特性:


  • 直接映射到利用体系线程:每个 Thread 实例对应一个利用体系线程
  • 手动管理:必要手动创建,启动和烧毁线程,以及处理处罚线程同步题目
  • 开销较大:创建和烧毁线程的开销较大,过多的线程大概导致体系性能降落
使用场景:


  • 必要对线程有风雅的控制,好比设置线程优先级,堆栈巨细,文化信息等
  • 特定场景下必要手动管理线程的生命周期
示例代码:
  1.     // 创建第一个线程
  2.     Thread thread1 = new Thread(() =>
  3.     {
  4.         for (int i = 0; i < 5; i++)
  5.         {
  6.             Console.WriteLine($"线程1正在执行: {i}");
  7.             Thread.Sleep(2000); // 暂停2秒
  8.         }
  9.     });
  10.     // 创建第二个线程
  11.     Thread thread2 = new Thread(new ThreadStart(Thread2Method));
  12.     // 启动线程
  13.     Console.WriteLine("开始执行线程...");
  14.     thread1.Start();
  15.     thread2.Start();
  16.     // 等待线程结束
  17.     //Join方法用于等待线程结束,即等待线程中的代码执行完毕。
  18.     thread1.Join();
  19.     thread2.Join();
  20.     Console.WriteLine("所有线程执行完毕!");
  21.     Console.ReadKey();
  22. }
  23. // 第二个线程要执行的方法
  24. static void Thread2Method()
  25. {
  26.     for (int i = 0; i < 5; i++)
  27.     {
  28.         Console.WriteLine($"线程2正在执行: {i}");
  29.         Thread.Sleep(800); // 暂停0.8秒
  30.     }
  31. }
复制代码
2.Task

界说:


  • System.Threading.Tasks.Task 类代表一个异步利用,可以明白为更高级别的异步编程抽象
特性:


  • 基于任务的异步模式(TAP):使用任务来表现异步利用,可以更方便地组合,链接和处理处罚任务
  • 线程池:Task 默认会使用线程池中的线程,而不是创建新的线程,从而淘汰开销
  • 支持结果值:Task<TResult> 可以返回盘算结果
  • 与 async/await 协同工作:Task 可以与 async/await 关键字共同使用,简化异步编程
使用场景:


  • 实行异步利用,无需手动管理线程。
  • 必要组合多个异步利用,或处理处罚异步利用的结果。
    1. static async Task Main(string[] args)
    2.         {
    3.             Console.WriteLine("开始任务示例...");
    4.             // 1. 基本的异步任务
    5.             await SimpleTaskAsync();
    6.             // 2. 带返回值的任务
    7.             int result = await CalculateAsync();
    8.             Console.WriteLine($"计算结果: {result}");
    9.             // 3. 并行任务
    10.             await ParallelTasksAsync();
    11.             // 4. 任务超时处理
    12.             await TaskWithTimeoutAsync();
    13.             Console.WriteLine("所有任务完成!");
    14.             Console.ReadKey();
    15.         }
    16.         // 基本异步任务
    17.         static async Task SimpleTaskAsync()
    18.         {
    19.             Console.WriteLine("开始简单任务");
    20.             await Task.Delay(1000); // 模拟耗时操作
    21.             Console.WriteLine("简单任务完成");
    22.         }
    23.         // 带返回值的异步任务
    24.         static async Task<int> CalculateAsync()
    25.         {
    26.             Console.WriteLine("开始计算");
    27.             await Task.Delay(2000); // 模拟复杂计算
    28.             return 42;
    29.         }
    30.         // 并行任务示例
    31.         static async Task ParallelTasksAsync()
    32.         {
    33.             Console.WriteLine("开始并行任务");
    34.             
    35.             var task1 = Task.Run(async () =>
    36.             {
    37.                 await Task.Delay(1000);
    38.                 Console.WriteLine("任务1完成");
    39.             });
    40.             var task2 = Task.Run(async () =>
    41.             {
    42.                 await Task.Delay(2000);
    43.                 Console.WriteLine("任务2完成");
    44.             });
    45.             // 等待所有任务完成
    46.             await Task.WhenAll(task1, task2);
    47.             Console.WriteLine("所有并行任务完成");
    48.         }
    49.         // 带超时的任务
    50.         static async Task TaskWithTimeoutAsync()
    51.         {
    52.             Console.WriteLine("开始超时任务");
    53.             
    54.             try
    55.             {
    56.                 using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(2));
    57.                 await Task.Delay(3000, cts.Token); // 这个任务会超时
    58.                 Console.WriteLine("此行不会执行");
    59.             }
    60.             catch (TaskCanceledException)
    61.             {
    62.                 Console.WriteLine("任务已超时");
    63.             }
    64.         }
    复制代码
3.async/await

界说:async/await是 C# 中用于简化异步编程的关键字
特性:


  • async 方法:使用 async 修饰的方法表现其内部大概包罗异步利用,可以使用 await 关键字
  • await 关键字:用于等候一个异步任务完成,而不会壅闭当火线程
  • 编译器支持:编译器会将 async 方法转换为状态机,处理处罚异步利用的调治
使用场景:


  • 盼望以同步的方式编写异步代码,进步代码的可读性和维护性。
  • 在 GUI 或服务器应用中,防止长时间的利用壅闭线程。
三.Thread,Task和async/await关键字的详细对比

1.Thread和Task的详细对比

  1. // Thread 示例
  2. Thread thread = new Thread(() =>
  3. {
  4.     Console.WriteLine("使用 Thread 执行工作");
  5.     Thread.Sleep(1000);
  6. });
  7. thread.Start();
  8. // Task 示例
  9. Task task = Task.Run(() =>
  10. {
  11.     Console.WriteLine("使用 Task 执行工作");
  12.     Thread.Sleep(1000);
  13. });
复制代码
重要区别:
Thread:


  • 直接映射到利用体系线程


  • 资源开销大


  • 无法直接返回结果


  • 不易于管理和组合
Task:


  • 使用线程池


  • 可以返回结果


  • 支持取消、一连、非常处理处罚


  • 易于组合和管理
2.Task 与 async/await 的共同使用

  1. // Task 单独使用
  2. public Task<int> GetDataAsync()
  3. {
  4.     return Task.Run(() =>
  5.     {
  6.         // 执行一些耗时操作
  7.         Thread.Sleep(1000);
  8.         return 42;
  9.     });
  10. }
  11. // 使用 async/await
  12. public async Task<int> GetDataAsyncWithAwait()
  13. {
  14.     Console.WriteLine("开始");
  15.     await Task.Delay(1000); // 异步等待
  16.     Console.WriteLine("结束");
  17.     return 42;
  18. }
复制代码
3. async/await 的现实应用场景

  1. // 文件操作示例
  2. public async Task SaveFileAsync(string content)
  3. {
  4.     Console.WriteLine("开始保存文件");
  5.     await File.WriteAllTextAsync("test.txt", content);
  6.     Console.WriteLine("文件保存完成");
  7. }
  8. // 多个异步操作组合
  9. public async Task ProcessDataAsync()
  10. {
  11.     try
  12.     {
  13.         // 并行执行多个异步操作
  14.         var task1 = Task.Delay(1000);
  15.         var task2 = Task.Delay(2000);
  16.         
  17.         await Task.WhenAll(task1, task2);
  18.         
  19.         // 串行执行异步操作
  20.         var result1 = await GetDataAsync();
  21.         var result2 = await ProcessResultAsync(result1);
  22.     }
  23.     catch (Exception ex)
  24.     {
  25.         Console.WriteLine($"错误: {ex.Message}");
  26.     }
  27. }
复制代码
4.关键区别总结

1)实行模子:


  • Thread: 一个线程实行一个任务


  • Task: 可以使用线程池,更机动


  • async/await: 不创建新线程,而是管理异步利用
2)资源使用:


  • Thread: 每个线程占用约1MB内存


  • Task: 更轻量级,共享线程池


  • async/await: 险些没有额外开销
3)使用场景:


  • Thread: 必要直接控制线程时


  • Task: 实行背景利用,必要返回结果时


  • async/await: IO利用,网络哀求等不必要CPU盘算的利用
4)代码可维护性:


  • Thread: 较难管理和维护


  • Task: 提供更好的控制和组合


  • async/await: 提供最清楚的代码结构
   在现实的开辟中优先使用 async/await 处理处罚异步利用,必要并行盘算时使用 Task,只在特别环境下使用 Thread
  
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表