杨中科 ASP.NETCORE 异步编程二

一、不要用sleep()

如果想在异步方法中暂停一段时间,不要用Thread.sleep(),因为它会阻塞调用线程,而要用await.Task.Delay()。

举例:
下载一个网址,3秒后下载另一个

示例:

sleep()

为了能直观看到效果,使用winform项目

在这里插入图片描述
在这里插入图片描述
此时点击按钮之后,页面便卡死不动了,不能在进行操作。因为Sleep()方法,阻塞了主线程。
睡眠结束后,才能继续操纵界面

注释后,便能在下载过程中,继续操作页面
在这里插入图片描述

await task.delay()

不会阻塞主线程

在这里插入图片描述
此时界面也是可正常操作

在控制台中没看到区别,但是放到WinForm程序中就能看到区别了ASP.NET Core中也看不到区别但是sleep()会降低并发

二、CancellationToken

概念:

多线程一般用于处理比较耗时的操作,
有时需要提前终止任务,比如:
请求超时、用户取消请求。很多异步方法都有
CancellationToken参数,用于获得提前终止执行的信号。
(下载文件暂停,用户关闭网页请求终止)

方法:

CancellationToken结构体
None:空
)bool lsCancellationRequested是否取消(用于判断请求者,是否终止请求)
Register(Action callback)注册取消监听
(
)Throw lfcancellationRequested()如果任务被取消,执行到这句话就抛异常

CancellationTokenSource
CancelAfter()超时后发出取消信号
Cancel()发出取消信号
CancellationToken Token

示例:

为“下载一个网址N次”的方法增加取消功能。
分别用GetstringAsync+IsCancellationRequested、GetStringAsync+ThrowlfCancellatiorRequested()、带CancellationToken的GetAsync()分别实现:取消分别用超时、用户敲按键(不能await)实现。

1.普通方式

在这里插入图片描述

运行结果:
在这里插入图片描述
下载一百遍终止。

2.加入cancellationtoken

在这里插入图片描述
调用
在这里插入图片描述

调用结果:
请求被取消

在这里插入图片描述

3.cancellationToken.ThrowIfCancellationRequested()

在这里插入图片描述

运行结果,会抛出异常
在这里插入图片描述

4.调用封装好的getAsync()方法

在这里插入图片描述
在这里插入图片描述
运行结果
抛出异常

在这里插入图片描述

cancel() 手动取消

在这里插入图片描述

ASP.NET Core开发中,一般不需要自已处理CancellationToken.
CancellationTokenSource这些,只要做到“能转发CancellationToken就转发即可。ASP.NET Core会对于用户请求中断进行处理。
(*)演示一下ASP.NETCore中的使用:写一个方法,Delay1000次,用Debug.WriteLine()输出,访问中间跳到放到其他网站。

在这里插入图片描述
访问其他网站的时候,就会抛出异常,暂停下载
在这里插入图片描述

三、WhenAll()

Task类的重要方法:

  1. Task WhenAny(lEnumerabletasks)等,任何一个Task完成,Task就完成
  2. Task<TResult[]> WhenAll(paramsTask[]tasks)等,所有Task完成,Task才完成。用于等待多个任务执行结束,但是不在乎它们的执行顺序。
  3. FromResult()创建普通数值的Task对象。

示例

Task tl =File.ReadAllTextAsync(“d:/l.txt”);
Task t2 =File.ReadAllTextAsync(“d:/2.txt”);
Task t3 =File.ReadAllTextAsync(“d:/3.txt”);
string[] results = await Task.WhenAll(t1, t2, t3)
string s1 = results[0];
string s2 = results[1];
string s3 = results[2];

1.whenall

在这里插入图片描述

运行结果
在这里插入图片描述

案例:

计算一个文件夹下,所有文本文件的单词个数汇总。
在这里插入图片描述
运行结果
在这里插入图片描述

四、异步其他问题

接口中的异步方法:

async是提示编译器为异步方法中的await代码进行分段处理的,而一个异步方法是否修饰了async对于方法的调用者来讲没区别的,因此对于接口中的方法或者抽象方法不能修饰为async。

在这里插入图片描述
在实现类中添加async

在这里插入图片描述

异步与yield:

复习: yield return不仅能够简化数据的返回,而且可以让数据处理“流水线化”,提升性能。

static lEnumerable<string> Test()
{
	yield return "hello",
	yield return "'yzk" ;
	yield return "'youzack";
}

在这里插入图片描述
运行结果
在这里插入图片描述
在旧版C#中,async方法中不能用yield。
从C#8.0开始,把返回值声明为IAsyncEnumerable(不要带Task),然后遍历的时候用await foreach()即可。

static async Task Main(string[] args)
{
	await foreach(var s in Test())
	Console.WriteLine(s);
}

static async lAsyncEnumerable<string> Test()
{
	yield return "hello";
	yield return "yzk";
	yield return "youzack";
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值