经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C# » 查看文章
C#异步有多少种实现方式?
来源:cnblogs  作者:追逐时光者  时间:2023/5/10 9:24:06  对本文有异议

前言

  微信群里的一个提问引发的这个问题,有同学问:C#异步有多少种实现方式?想要知道C#异步有多少种实现方式,首先我们要知道.NET提供的执行异步操作的三种模式,然后再去了解C#异步实现的方式。

.NET异步编程模式

.NET 提供了执行异步操作的三种模式:

  • 基于任务的异步模式 (TAP) ,该模式使用单一方法表示异步操作的开始和完成。 TAP 是在 .NET Framework 4 中引入的。 这是在 .NET 中进行异步编程的推荐方法。 C# 中的 async 和 await 关键词以及 Visual Basic 中的 Async 和 Await 运算符为 TAP 添加了语言支持。 有关详细信息,请参阅基于任务的异步模式 (TAP)

  • 基于事件的异步模式 (EAP),是提供异步行为的基于事件的旧模型。 这种模式需要后缀为 Async 的方法,以及一个或多个事件、事件处理程序委托类型和 EventArg 派生类型。 EAP 是在 .NET Framework 2.0 中引入的。 建议新开发中不再使用这种模式。 有关详细信息,请参阅基于事件的异步模式 (EAP)

  • 异步编程模型 (APM) 模式(也称为 IAsyncResult 模式),这是使用 IAsyncResult 接口提供异步行为的旧模型。 在这种模式下,同步操作需要 Begin 和 End 方法(例如,BeginWrite 和 EndWrite以实现异步写入操作)。 不建议新的开发使用此模式。 有关详细信息,请参阅异步编程模型 (APM)

C#异步有四种实现方式

C# 异步有多种实现方式,可归纳为以下几类:

1、异步方法(Async Method TAP模式

使用async/await关键字实现异步编程,这是比较常用的一种异步实现方式。例如:

  1. public async Task TestDoSomeAsync()
  2. {
  3. await Task.Delay(1000*10);
  4. Console.WriteLine("Async method completed.");
  5. }

2、任务并行库(TPL, Task Parallel Library TAP模式

通过 Task 和 Task<T> 类型实现异步编程,可以利用多核处理器,并发执行多个独立的任务。例如:

  1. public static void TestTaskParallel()
  2. {
  3. var task1 = Task.Run(() =>
  4. {
  5. Console.WriteLine("Task 1 completed.");
  6. });
  7. var task2 = Task.Run(() =>
  8. {
  9. Console.WriteLine("Task 2 completed.");
  10. });
  11. Task<int> task3 = Task.Factory.StartNew(() =>
  12. {
  13. Console.WriteLine("Task 3 completed.");
  14. return 20;// 返回一个整数值
  15. });
  16. //等待所有任务完成
  17. Task.WaitAll(task1, task2, task3);
  18. }

3、Asynchronous Programming Model(APM模式)

是一种经典的异步编程模式,需要手动创建回调函数,用于处理完成或错误的通知。可以通过 IAsyncResult 设计模式的 Begin 和 End 方法来实现,其中 Begin 方法开始异步操作,而 End 方法在异步操作完成时执行,并返回异步操作的结果。

需要注意的是,APM 模式通过 IAsyncResult 接口来存储异步操作的状态和结果,相对比较复杂,代码量也较大。同时,在使用 APM 模式时,还需要手动处理回调函数和等待异步操作完成等细节工作,使得开发起来相对较为繁琐。

  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. // 创建异步操作类实例
  6. MyAsyncClass asyncClass = new MyAsyncClass();
  7. // 开始异步操作
  8. IAsyncResult result = asyncClass.BeginDoWork(null, null);
  9. // 主线程执行其他操作
  10. // 等待异步操作完成并获取结果
  11. int res = asyncClass.EndDoWork(result);
  12. // 处理异步操作的结果
  13. Console.WriteLine("Result: " + res);
  14. Console.ReadLine();
  15. }
  16. }
  17. class MyAsyncClass
  18. {
  19. /// <summary>
  20. /// 异步执行的方法
  21. /// </summary>
  22. /// <param name="callback">callback</param>
  23. /// <param name="state">state</param>
  24. /// <returns></returns>
  25. public IAsyncResult BeginDoWork(AsyncCallback callback, object state)
  26. {
  27. // 创建一个新的异步操作对象
  28. MyAsyncResult result = new MyAsyncResult(state);
  29. // 开始异步操作
  30. Thread thread = new Thread(() =>
  31. {
  32. try
  33. {
  34. // 执行一些操作
  35. int res = 1 + 2;
  36. // 设置异步操作的结果
  37. result.Result = res;
  38. // 触发回调函数
  39. callback?.Invoke(result);
  40. }
  41. catch (Exception ex)
  42. {
  43. // 设置异步操作的异常
  44. result.Error = ex;
  45. // 触发回调函数
  46. callback?.Invoke(result);
  47. }
  48. });
  49. thread.Start();
  50. // 返回异步操作对象
  51. return result;
  52. }
  53. /// <summary>
  54. /// 结束异步执行的方法
  55. /// </summary>
  56. /// <param name="result">result</param>
  57. /// <returns></returns>
  58. public int EndDoWork(IAsyncResult result)
  59. {
  60. // 将 IAsyncResult 转换为 MyAsyncResult 类型,并等待异步操作完成
  61. MyAsyncResult myResult = (MyAsyncResult)result;
  62. myResult.AsyncWaitHandle.WaitOne();
  63. // 在异步操作中抛出异常
  64. if (myResult.Error != null)
  65. {
  66. throw myResult.Error;
  67. }
  68. // 返回异步操作的结果
  69. return myResult.Result;
  70. }
  71. }
  72. class MyAsyncResult : IAsyncResult
  73. {
  74. public bool IsCompleted => AsyncWaitHandle.WaitOne(0);
  75. public WaitHandle AsyncWaitHandle { get; } = new ManualResetEvent(false);
  76. public object AsyncState { get; }
  77. public bool CompletedSynchronously => false;
  78. public int Result { get; set; }
  79. /// <summary>
  80. /// 存储异步操作的结果或异常信息
  81. /// </summary>
  82. public Exception Error { get; set; }
  83. /// <summary>
  84. /// 构造函数
  85. /// </summary>
  86. /// <param name="asyncState">asyncState</param>
  87. public MyAsyncResult(object asyncState)
  88. {
  89. AsyncState = asyncState;
  90. }
  91. }

4、Event-based Asynchronous Pattern(EAP模式)

一种已过时的异步编程模式,需要使用事件来实现异步编程。例如:

需要注意的是,EAP 模式通过事件来实现异步编程,相对于 APM 模式更加简洁易懂,同时也避免了手动处理回调函数等细节工作。但是,EAP 模式并不支持 async/await 异步关键字,因此在一些特定的场景下可能不够灵活。

  1. public class MyAsyncClass : Component
  2. {
  3. /// <summary>
  4. /// 声明一个委托类型,用于定义异步操作的方法签名
  5. /// </summary>
  6. /// <param name="arg"></param>
  7. /// <returns></returns>
  8. public delegate int MyAsyncDelegate(int arg);
  9. /// <summary>
  10. /// 声明一个事件,用于通知异步操作的完成
  11. /// </summary>
  12. public event MyAsyncDelegate OperationNameCompleted;
  13. /// <summary>
  14. /// 异步执行方法,接受一个参数 arg
  15. /// </summary>
  16. /// <param name="arg"></param>
  17. public void DoWorkAsync(int arg)
  18. {
  19. // 将异步操作放入线程池中执行
  20. ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork), arg);
  21. }
  22. /// <summary>
  23. /// 真正的异步操作
  24. /// </summary>
  25. /// <param name="obj"></param>
  26. private void DoWork(object obj)
  27. {
  28. int arg = (int)obj;
  29. int res = arg + 1;
  30. // 触发事件,传递异步操作的结果
  31. OperationNameCompleted?.Invoke(res);
  32. }
  33. }

参考文章

https://learn.microsoft.com/zh-cn/dotnet/standard/asynchronous-programming-patterns/

 

 

原文链接:https://www.cnblogs.com/Can-daydayup/p/17383651.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号