假设我想确保从异步方法返回的任务对象将由于调用者的取消请求而转换为已取消状态。
问题是:无论上述方法使用的异步方法如何实现以及它们是否完成,都应该发生这种情况。
考虑以下扩展方法:
public static Task<T> ToTask<T>(this CancellationToken cancellationToken)
{
var tcs = new TaskCompletionSource<T>();
cancellationToken.Register(() => { tcs.SetCanceled(); });
return tcs.Task;
}
我现在可以使用这样的任务来确保上述场景:
public async Task<Item> ProvideItemAsync(CancellationToken cancellationToken)
{
Task<Item> cancellationTask = cancellationToken.ToTask<Item>();
Task<Item> itemTask = _itemProvider.ProvideItemAsync(cancellationToken);
Task<Task<Item>> compoundTask = Task.WhenAny(cancellationTask, itemTask);
Task<Item> finishedTask = await compoundTask;
return await finishedTask;
}
我的问题是:
1) 这种方法有什么问题吗?
2)是否有内置的API来促进这样的用例
谢谢!
最佳答案
Suppose I want to ensure the cancellation of an asynchronous operation, Regardless of how the actual operation is implemented and whether or not it completes.
除非将代码包装到单独的进程中,否则这是不可能的。
When I say "ensure", I mean to say that the task denoting said operation transitions into the canceled state.
如果您只想取消任务(而不是操作本身),那么当然可以这样做。
Are there any issues with this approach?
这里有一些棘手的边缘情况。特别是,如果任务成功完成,您需要处理 Register
的结果。
我建议使用WaitAsync
extension method在我的AsyncEx.Tasks
library :
public Task<Item> ProvideItemAsync(CancellationToken cancellationToken)
{
return _itemProvider.ProvideItemAsync(cancellationToken).WaitAsync(cancellationToken);
}
关于c# - 确保取消某些任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40262991/