c# - 在没有冗余 CancellationTokenSource 的情况下链接两个 CancellationToken
问题描述
在获得CancellationToken
( StartAsync
) 的方法中,我想添加一个内部CancellationToken
函数,以便调用者可以在外部或内部(例如通过调用AbortAsync()
方法)取消异步操作。
AFAIK,这样做的方法是使用CreateLinkedCancellationTokenSource
. 但它的 API 似乎相当不舒服,因为我需要为此创建两个额外CancellationTokenSource
的实例,并且因为它们实现了IDisposable
,我也必须不要忘记处置它们。因此,我需要将它们都存储为成员以供以后处理。
我错过了什么吗?我觉得应该有一种更简单的方法可以将额外的取消机制附加到现有令牌上,而不会强迫我维护两个CancellationTokenSource
实例。
public Task StartAsync(CancellationToken externalToken)
{
this.actualCancellation = new CancellationTokenSource();
this.linkedCancellation = CancellationTokenSource.CreateLinkedTokenSource(
actualCancellation.Token, externalToken);
this.execution = this.ExecuteAsync(this.linkedCancellation.Token);
return this.execution;
}
public async Task AbortAsync()
{
try
{
this.actualCancellation.Cancel();
await this.execution;
}
catch
{
}
finally
{
this.actualCancellation.Dispose();
this.linkedCancellation.Dispose();
}
}
解决方案
链接取消源不是一种特殊的取消源。它是一个常规的取消源,也“链接”到现有令牌 - 即,当现有令牌被取消时,源将被取消。在所有其他方面,它是一个正常的取消源,因此您可以像任何其他取消源一样自行取消它。
因此,您只需要一个取消源 - 一个链接到现有令牌并且也可以手动取消的源:
public Task StartAsync(CancellationToken externalToken)
{
this.linkedCancellation = CancellationTokenSource.CreateLinkedTokenSource(externalToken);
this.execution = this.ExecuteAsync(this.linkedCancellation.Token);
return this.execution;
}
public async Task AbortAsync()
{
try
{
this.linkedCancellation.Cancel();
await this.execution;
}
catch
{
}
finally
{
this.linkedCancellation.Dipose();
}
}
顺便说一句,我会仔细考虑这种 API 设计的生命周期问题。目前StartAsync
做资源分配和AbortAsync
清理;我推荐一种由构造函数和Dispose
(RAII)处理的设计。
推荐阅读
- typescript - 从 .d.ts 文件导出和导入 Typescript 类型别名
- jquery - Laravel 5.8 多张图片上传
- sql - 如何在 PowerShell 中运行多个 SQL 查询“加载本地 infile”?
- java - Android 如何让从 firebase 数据库加载数据与 orderByChild() & startAt() & limitToFirst() 结合使用?
- javascript - 当我刷新不同的路由路径时,Firebase 身份验证会重置
- javascript - 无法在 jQuery 函数中返回 $.posted php 文件数据
- jquery - 如何使用 Squelize 修复 RAW 查询
- arrays - autohotkey array null ...你如何检查数组是否为空/空?
- javascript - Javascript regex 查找除 html 标签内的文本之外的所有内容,并排除一些标签
- git - 如何在不合并的情况下将来自另一个分支的特定文件添加到我的分支?