asp.net core中,使用CancellationToken在用户终止请求时取消所有异步操作+ abp中的设计
如果一个controller.action里的处理非常耗时,比如读数据库、文件操作、调用第三方接口等
此时用户随时可能关闭浏览器、f5刷新网页等操作。
但是服务端的耗时代码任然在执行,这太浪费了,既然用户终止请求了,我们就应该取消所有的耗时操作
在.net开发中,几乎所有的异步方法都有个cancellationtoken类型的参数,只要我们传入此令牌,将来我们随时可以通过此令牌取消异步操作
而asp.net中httpcontext提供了一个requestaborted属性,它就是cancellationtoken类型,当用户以任何方式终止请求时, httpcontext.requestaborted就会触发取消
所以如果我们在异步方法中都传入这个参数,就能实现当用户终止请求时,我们所有的异步操作都会立即取消
并发大的情况下,这个操作很重要。
参考代码:
1 public async task<actionresult> testasync() 2 { 3 await system.io.file.readalltextasync(@"d:\a.txt", httpcontext.requestaborted); 4 //....略
上面是asp.net默认行为,你会发现一个问题,真个应用程序有铺天盖地的异步方法,如果都想实现上述特征 我们所有的异步方法都得加上cancellationtoken参数
abp提供了一种牛x的方式
它提供一个icancellationtokenprovider接口,它会为我们提供一个cancellationtoken对象,所以我们定义的异步方法不需要定义cancellationtoken参数了,首先在我们的类中依赖注入这个接口,然后在调用.net内置库或第三方库的异步方法时,传入icancellationtokenprovider.token就可以了,如下:
1 icancellationtokenprovider cancellationtokenprovider ; 2 3 //构造函数注入cancellationtokenprovider 略... 4 5 public override async task<list<tentity>> getalllistasync() 6 { 7 return await getall().tolistasync(cancellationtokenprovider.token); 8 }
比较推荐的是使用“空模式”,用属性注入,如下:
1 public icancellationtokenprovider cancellationtoken { get; set; } = nullcancellationtokenprovider.instance;
abp中最终使用的是httpcontextcancellationtokenprovider,它的token属性返回的就是httpcontext.requestaborted
默认情况下abp的repository中的所有异步方法已经使用这种模式,由于我们开发是大部分情况下都是数据库读写,所以我们在abp中几乎可以不关心这事,默认就是以合理的方式运行的。
但有时候我们需要做其它异步操作,比如调用第三方接口啥的,此时就需要通过上面的方式来实现这种 用户取消请求则所以异步操作理解取消的效果。
在某些场景中我们可能并不想用这种默认的行为,而是希望传入自己的cancellationtoken对象,而不是用httpcontext的。这是我估计icancellationtokenprovider.use就派上用场了。怎么用呢?
上一篇: 永久免费!国产操作系统 Deepin V20 Beta版发布(附安装教程)
下一篇: WPF入门学习