posted at 2020.10.21 14:14 by 风信子
异步等待语法主要由一对语言关键字组成:async和await,这两个关键字通常是成对出现的。要让方法支持异步等待,必须让方法的返回类型为Task或Task<TResult>。方法的名称可以用“Async”结尾,以标注它是异步方法,例如RunAsync、DownloadAsync等。
调用异步方法时,可以加上await关键字,表示异步等待。在调用异步方法时,当前线程会进入等待状态,但不会阻塞;当异步方法执行完成后,会回到当前线程中并继续执行后面的代码。在使用了await关键字的方法中需要加上async关键字,表示调用了异步代码。
综上所述,异步方法的声明方法就是让它返回Task或Task<TResult>实例。
7.1或以上版本的C#语言支持在Main方法中进行异步等待,使用方法为:在Main方法中使用await关键字调用异步方法,然后在Main方法中添加async关键字进行修饰。
在实际开发中,经常会遇到在后台使用Task执行一些比较耗时间代码的情况,出于友好的用户体验,在执行长时间任务的过程中应该向用户反馈处理进度;此外,由于运行耗时较长,用户可能不想再继续等待,应该允许用户取消任务。
CancellationTokenSource类提供了取消任务的处理模型,通过Token属性可以获得CancellationToken结构实例的副本。所有被复制的CancellationToken对象都会监听CancellationTokenSource实例的状态,一旦CancellationTokenSource实例调用了Cancel方法,各个CancellationToken副本就会收到通知,此时CancellationToken对象的IsCancellationRequested属性就会返回true。可以通过检查IsCancellationRequested属性来判断并行任务是否被取消。
下面一个实例将演示一个累加运算,计算过程用一个异步方法封装。调用方法时,可以传递一个整数值,表示参与累加运算的最大值,计算将从0开始累加,直到最大值,在程序执行过程中,用户随时可以按下C键取消任务。
1:新建一个控制台应用程序项目。
2:定义执行累加计算的异步方法。
static Task<int> RunAsync(int maxNum, CancellationToken token = default)
{
TaskCompletionSource<int> tcl = new TaskCompletionSource<int>();
int x = 0;
int res = 0;
while(x < maxNum)
{
if (token.IsCancellationRequested)
{
break;
}
res += x;
x += 1;
Task.Delay(500).Wait();
}
tcl.SetResult(res);
return tcl.Task;
}
Token参数用于监听任务是否被取消。本方法中使用了TaskCompletionSource<TResult>类,这个类可以灵活地设置Task的运行结果(通过SetResult方法设置),再访问Task属性就能获取要返回的并行任务实例。
3:在Main方法中实例化CancellationTokenSource。
CancellationTokenSource cansrc = new CancellationTokenSource();
4:在调用累加计算的异步方法之前,可以开启一个并行任务,用于判断用户是否按下了C键,如果是,就调用CancellationTokenSource 对象的Cancel方法。
Task.Run(() =>
{
Console.WriteLine("按 C 键取消任务。");
while (true)
{
var info = Console.ReadKey(true);
if (info.Key == ConsoleKey.C)
{
cansrc.Cancel();
break;
}
}
});
5:调用异步方法,并等待计算完成。
int result = await RunAsync(200, cansrc.Token);
Console.WriteLine("计算结果:{0}", result);
访问Token属性,会复制一份CancellationToken实例,并能够监听Cancel方法的调用。
6:当不再使用CancellationTokenSource对象时,需要将其释放。
cansrc.Dispose();
7:运行应用程序,累加计算开始。此过程中如果按下C键,任务被取消,并把已经完成的部分计算结果返回,如图所示。
a728ceca-3242-4970-8753-07b4613470c2|0|.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04
Tags: C#, 程序, 代码, 方法, 类, 模
IT技术