我需要取消返回任务的API调用,但它不会将CancellationToken作为参数,我也无法添加。
如何取消该任务?
在这种特殊情况下,我正在使用带有Geocoder对象的Xamarin.Forms。
IEnumerable<Position> positions = await geo.GetPositionsForAddressAsync(address);
这个电话有时需要很长时间。对于我的一些用例,用户只需导航到另一个屏幕,就不再需要该任务的结果。
我还担心我的应用程序会暂停,并且没有停止这个长时间运行的任务,或者任务完成并且需要不再有效的代码。
答案 0 :(得分:8)
我读到的关于这样做的最好的是来自Stephen Toub on the "Parallel Programming with .NET" blog。
基本上你创建了自己的取消'重载':
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来调用异步函数:
try
{
await op.WithCancellation(token);
}
catch(OperationCanceledException)
{
op.ContinueWith(t => /* handle eventual completion */);
… // whatever you want to do in the case of cancellation
}
真的需要阅读他的博客帖子......
答案 1 :(得分:4)
简而言之......不能取消不会尝试观察CancellationToken的c#任务,至少在你所指的上下文中是这样。 (例如,结束应用程序,会这样做)
https://jsfiddle.net/q3hhk17e/12/上的链接讨论了如何利用取消令牌的各种模式,但由于您正在处理您无法控制的库,因此您无法做多少事情。