有没有可能取消一个没有CancellationToken的c#任务?
本文关键字:CancellationToken 任务 一个 有可能 取消 | 更新日期: 2023-09-27 18:10:58
我需要取消一个API调用,返回一个任务,但它不接受一个CancellationToken作为参数,我不能添加一个。
如何取消该任务?
在本例中,我使用Xamarin。表单与Geocoder对象。
IEnumerable<Position> positions = await geo.GetPositionsForAddressAsync(address);
这个调用有时需要很长时间。对于我的一些用例,用户可以导航到另一个屏幕,并且不再需要该任务的结果。
我也担心我的应用程序进入睡眠状态,没有这个长时间运行的任务停止,或者任务完成,需要的代码不再有效。
我读过的关于这方面的最好的文章来自Stephen Toub的"Parallel Programming with . net "博客。
基本上你可以创建自己的取消'overload':
public static async Task<T> WithCancellation<T>(
this Task<T> task, CancellationToken cancellationToken)
{
var tcs = new TaskCompletionSource<bool>();
using(cancellationToken.Register(
s => ((TaskCompletionSource<bool>)s).TrySetResult(true), tcs))
if (task != await Task.WhenAny(task, tcs.Task))
throw new OperationCanceledException(cancellationToken);
return await task;
}
然后使用try/catch来调用async函数:
try
{
await op.WithCancellation(token);
}
catch(OperationCanceledException)
{
op.ContinueWith(t => /* handle eventual completion */);
… // whatever you want to do in the case of cancellation
}
真的需要读一下他的博客…
总之…不,取消一个没有尝试观察CancellationToken的c#任务是不可能的,至少在你所指的上下文中是不可能的。(例如,结束应用程序,会这样做)
关于取消的链接讨论了如何利用取消令牌的各种模式,但由于您正在处理一个您无法控制的库,因此您可以做的事情不多。