当前位置:   article > 正文

在 C# 中使用 async、await、Task 进行异步编程_c# async task

c# async task

C# 和 .NET Framework(4.5 和核心)支持使用一些本机函数、类和保留关键字的异步编程。

在我们了解什么是异步编程之前,让我们通过下面的控制台示例来了解什么是同步编程。

示例:异步程序
 Copy
  1. static void Main(string[] args)
  2. {
  3. LongProcess();
  4. ShortProcess();
  5. }
  6. static void LongProcess()
  7. {
  8. Console.WriteLine("LongProcess Started");
  9. //some code that takes long execution time
  10. System.Threading.Thread.Sleep(4000); // hold execution for 4 seconds
  11. Console.WriteLine("LongProcess Completed");
  12. }
  13. static void ShortProcess() {
  14. Console.WriteLine("ShortProcess Started");
  15. //do something here
  16. Console.WriteLine("ShortProcess Completed");
  17. }
输出:
  1. LongProcess Started
  2. LongProcess Completed
  3. ShortProcess Started
  4. ShortProcess Completed

在上面的示例中,该LongProcess()方法是一些长时间运行的任务,例如从服务器读取文件、调用返回大量数据的 Web API 或上传或下载大文件。执行需要更长的时间(Thread.Sleep(4000)保持 4 秒只是为了显示较长的执行时间)。这ShortProcess()是一个在方法之后执行的简单LongProcess()方法。

上述程序同步执行。这意味着执行从Main()方法开始,首先执行LongProcess()方法,然后执行ShortProcess()方法。在执行期间,应用程序被阻塞并变得无响应(您主要可以在基于 Windows 的应用程序中看到这一点)。这称为同步编程,在当前行完全执行之前,执行不会转到下一行。

什么是异步编程?

在异步编程中,代码在线程中执行,而无需等待 I/O 绑定或长时间运行的任务完成。例如,在异步编程模型中,LongProcess()方法会在与线程池不同的线程中执行,主应用线程会继续执行下一条语句。

Microsoft 建议使用基于任务的异步模式在 .NET Framework 或 .NET Core 应用程序中使用asyncawait关键字和TaskTask<TResult>类  来实现异步编程。

async现在让我们使用关键字 以异步模式重写上面的示例。

示例:异步程序
 Copy
  1. static async Task Main(string[] args)
  2. {
  3. LongProcess();
  4. ShortProcess();
  5. }
  6. static async void LongProcess()
  7. {
  8. Console.WriteLine("LongProcess Started");
  9. await Task.Delay(4000); // hold execution for 4 seconds
  10. Console.WriteLine("LongProcess Completed");
  11. }
  12. static void ShortProcess() {
  13. Console.WriteLine("ShortProcess Started");
  14. //do something here
  15. Console.WriteLine("ShortProcess Completed");
  16. }
输出:
  1. LongProcess Started
  2. ShortProcess Started
  3. ShortProcess Completed
  4. LongProcess Completed

在上面的例子中,Main()方法是用async关键字标记的,返回类型是Task. 关键字将该async方法标记为异步。注意方法链中的所有方法都必须是async为了实现异步编程。所以,Main()方法一定async要让子方法异步。

LongProcess()方法还标有async使其异步的关键字。await Task.Delay(4000);保持线程执行 4 秒 。

async Main()现在,程序从主应用程序线程中 的方法开始执行。该async LongProcess()方法在单独的线程中执行,主应用程序线程继续执行调用ShortProcess()方法的下一条语句并且不等待LongProcess()完成。

异步、等待和任务

如果方法将值返回给调用代码,则与和async一起使用 。我们只使用了上面程序中的关键字来演示简单的异步 void 方法。 awaitTaskasyncasync

await关键字等待该 方法async,直到它返回一个值。所以主应用程序线程停在那里,直到它收到一个返回值。

Task类表示异步操作, Task <TResult>泛型类表示可以返回值的操作。在上面的示例中,我们使用await Task.Delay(4000)了已启动async的操作,该操作会休眠 4 秒,并且 await 会持有一个线程直到 4 秒。

下面演示了async返回值的方法。

示例:异步方法返回值
 Copy
  1. static async Task Main(string[] args)
  2. {
  3. Task<int> result = LongProcess();
  4. ShortProcess();
  5. var val = await result; // wait untile get the return value
  6. Console.WriteLine("Result: {0}", val);
  7. Console.ReadKey();
  8. }
  9. static async Task<int> LongProcess()
  10. {
  11. Console.WriteLine("LongProcess Started");
  12. await Task.Delay(4000); // hold execution for 4 seconds
  13. Console.WriteLine("LongProcess Completed");
  14. return 10;
  15. }
  16. static void ShortProcess()
  17. {
  18. Console.WriteLine("ShortProcess Started");
  19. //do something here
  20. Console.WriteLine("ShortProcess Completed");
  21. }
输出:
  1. LongProcess Started
  2. ShortProcess Started
  3. ShortProcess Completed
  4. LongProcess Completed
  5. Result: 10

在上面的例子中,在静态async Task<int> LongProcess()方法中,Task<int>用于表示返回值类型为int。int val = await result;将在那里停止主线程,直到它在结果中填充返回值。一旦获得result变量中的值,它就会自动将一个整数分配给val.

async方法应该返回void,  Task, 或 Task<TResult>, 其中TResult是方法的返回 类型async。返回void通常用于事件处理程序。该async关键字允许我们在方法中使用 await 关键字,以便我们可以等待异步方法完成以用于其他依赖于返回值的方法。

如果您有多个async返回值的方法,那么您可以await在要在进一步步骤中使用返回值之前使用所有方法。

示例:异步方法
 Copy
  1. static async Task Main(string[] args)
  2. {
  3. Task<int> result1 = LongProcess1();
  4. Task<int> result2 = LongProcess2();
  5. //do something here
  6. Console.WriteLine("After two long processes.");
  7. int val = await result1; // wait untile get the return value
  8. DisplayResult(val);
  9. val = await result2; // wait untile get the return value
  10. DisplayResult(val);
  11. Console.ReadKey();
  12. }
  13. static async Task<int> LongProcess1()
  14. {
  15. Console.WriteLine("LongProcess 1 Started");
  16. await Task.Delay(4000); // hold execution for 4 seconds
  17. Console.WriteLine("LongProcess 1 Completed");
  18. return 10;
  19. }
  20. static async Task<int> LongProcess2()
  21. {
  22. Console.WriteLine("LongProcess 2 Started");
  23. await Task.Delay(4000); // hold execution for 4 seconds
  24. Console.WriteLine("LongProcess 2 Completed");
  25. return 20;
  26. }
  27. static void DisplayResult(int val)
  28. {
  29. Console.WriteLine(val);
  30. }
输出:
  1. LongProcess 1 Started
  2. LongProcess 2 Started
  3. After two long processes.
  4. LongProcess 2 Completed
  5. LongProcess 1 Completed
  6. 10
  7. 20

在上面的程序中,我们在需要将返回值传递给另一个方法之前执行了 await result1 和 await result2。

因此,您可以使用asyncC# 在 .NET Framework 或 .NET Core 中使用 、 await 和 Task 实现异步编程。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/104569
推荐阅读
相关标签
  

闽ICP备14008679号