赞
踩
C# 和 .NET Framework(4.5 和核心)支持使用一些本机函数、类和保留关键字的异步编程。
在我们了解什么是异步编程之前,让我们通过下面的控制台示例来了解什么是同步编程。
- static void Main(string[] args)
- {
- LongProcess();
-
- ShortProcess();
- }
-
- static void LongProcess()
- {
- Console.WriteLine("LongProcess Started");
-
- //some code that takes long execution time
- System.Threading.Thread.Sleep(4000); // hold execution for 4 seconds
-
- Console.WriteLine("LongProcess Completed");
- }
-
- static void ShortProcess() {
- Console.WriteLine("ShortProcess Started");
-
- //do something here
-
- Console.WriteLine("ShortProcess Completed");
- }
- LongProcess Started
- LongProcess Completed
- ShortProcess Started
- ShortProcess Completed
在上面的示例中,该LongProcess()
方法是一些长时间运行的任务,例如从服务器读取文件、调用返回大量数据的 Web API 或上传或下载大文件。执行需要更长的时间(Thread.Sleep(4000)
保持 4 秒只是为了显示较长的执行时间)。这ShortProcess()
是一个在方法之后执行的简单LongProcess()
方法。
上述程序同步执行。这意味着执行从Main()
方法开始,首先执行LongProcess()
方法,然后执行ShortProcess()
方法。在执行期间,应用程序被阻塞并变得无响应(您主要可以在基于 Windows 的应用程序中看到这一点)。这称为同步编程,在当前行完全执行之前,执行不会转到下一行。
在异步编程中,代码在线程中执行,而无需等待 I/O 绑定或长时间运行的任务完成。例如,在异步编程模型中,LongProcess()
方法会在与线程池不同的线程中执行,主应用线程会继续执行下一条语句。
Microsoft 建议使用基于任务的异步模式在 .NET Framework 或 .NET Core 应用程序中使用async、await关键字和Task或Task<TResult>类 来实现异步编程。
async
现在让我们使用关键字 以异步模式重写上面的示例。
- static async Task Main(string[] args)
- {
- LongProcess();
-
- ShortProcess();
- }
-
- static async void LongProcess()
- {
- Console.WriteLine("LongProcess Started");
-
- await Task.Delay(4000); // hold execution for 4 seconds
-
- Console.WriteLine("LongProcess Completed");
-
- }
-
- static void ShortProcess() {
- Console.WriteLine("ShortProcess Started");
-
- //do something here
-
- Console.WriteLine("ShortProcess Completed");
- }
- LongProcess Started
- ShortProcess Started
- ShortProcess Completed
- LongProcess Completed
在上面的例子中,Main()
方法是用async
关键字标记的,返回类型是Task
. 关键字将该async
方法标记为异步。注意方法链中的所有方法都必须是async
为了实现异步编程。所以,Main()
方法一定async
要让子方法异步。
该LongProcess()
方法还标有async
使其异步的关键字。await Task.Delay(4000);
保持线程执行 4 秒 。
async Main()
现在,程序从主应用程序线程中 的方法开始执行。该async LongProcess()
方法在单独的线程中执行,主应用程序线程继续执行调用ShortProcess()
方法的下一条语句并且不等待LongProcess()
完成。
如果方法将值返回给调用代码,则与和async
一起使用 。我们只使用了上面程序中的关键字来演示简单的异步 void 方法。 await
Task
async
async
await
关键字等待该 方法async
,直到它返回一个值。所以主应用程序线程停在那里,直到它收到一个返回值。
Task类表示异步操作, Task <TResult>泛型类表示可以返回值的操作。在上面的示例中,我们使用await Task.Delay(4000)
了已启动async
的操作,该操作会休眠 4 秒,并且 await 会持有一个线程直到 4 秒。
下面演示了async
返回值的方法。
- static async Task Main(string[] args)
- {
- Task<int> result = LongProcess();
-
- ShortProcess();
-
- var val = await result; // wait untile get the return value
-
- Console.WriteLine("Result: {0}", val);
-
- Console.ReadKey();
- }
-
- static async Task<int> LongProcess()
- {
- Console.WriteLine("LongProcess Started");
-
- await Task.Delay(4000); // hold execution for 4 seconds
-
- Console.WriteLine("LongProcess Completed");
-
- return 10;
- }
-
- static void ShortProcess()
- {
- Console.WriteLine("ShortProcess Started");
-
- //do something here
-
- Console.WriteLine("ShortProcess Completed");
- }
- LongProcess Started
- ShortProcess Started
- ShortProcess Completed
- LongProcess Completed
- 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
在要在进一步步骤中使用返回值之前使用所有方法。
- static async Task Main(string[] args)
- {
- Task<int> result1 = LongProcess1();
- Task<int> result2 = LongProcess2();
-
- //do something here
- Console.WriteLine("After two long processes.");
-
- int val = await result1; // wait untile get the return value
- DisplayResult(val);
-
- val = await result2; // wait untile get the return value
- DisplayResult(val);
-
- Console.ReadKey();
- }
-
- static async Task<int> LongProcess1()
- {
- Console.WriteLine("LongProcess 1 Started");
-
- await Task.Delay(4000); // hold execution for 4 seconds
-
- Console.WriteLine("LongProcess 1 Completed");
-
- return 10;
- }
-
- static async Task<int> LongProcess2()
- {
- Console.WriteLine("LongProcess 2 Started");
-
- await Task.Delay(4000); // hold execution for 4 seconds
-
- Console.WriteLine("LongProcess 2 Completed");
-
- return 20;
- }
-
- static void DisplayResult(int val)
- {
- Console.WriteLine(val);
- }
- LongProcess 1 Started
- LongProcess 2 Started
- After two long processes.
- LongProcess 2 Completed
- LongProcess 1 Completed
- 10
- 20
在上面的程序中,我们在需要将返回值传递给另一个方法之前执行了 await result1 和 await result2。
因此,您可以使用async
C# 在 .NET Framework 或 .NET Core 中使用 、 await 和 Task 实现异步编程。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。