简体   繁体   English

是否可以在没有CancellationToken的情况下取消C#任务?

[英]Is it possible to cancel a C# Task without a CancellationToken?

I'm need to cancel an API call that returns a Task, but it doesn't take a CancellationToken as a parameter, and I can't add one. 我需要取消返回任务的API调用,但它不会将CancellationToken作为参数,我不能添加一个。

How can I cancel that Task? 我该如何取消该任务?

In this particular case, I'm using Xamarin.Forms with the Geocoder object. 在这种特殊情况下,我正在使用带有Geocoder对象的Xamarin.Forms。

 IEnumerable<Position> positions = await geo.GetPositionsForAddressAsync(address); 

That call can sometimes take a very long time. 这个电话有时需要很长时间。 For some of my use cases, the user can just navigate to another screen, and that result of that task is no longer needed. 对于我的一些用例,用户可以只导航到另一个屏幕,并且不再需要该任务的结果。

I also worry about my app going to sleep and not having this long running task stopped, or of the task completing and having need of code which is no longer valid. 我也担心我的应用程序会进入休眠状态,并且没有停止长时间运行的任务,或者任务完成并且需要不再有效的代码。

The best that I have read about doing this is from Stephen Toub on the "Parallel Programming with .NET" blog . 我读到的关于这一点的最好的是来自Stephen Toub的“与.NET并行编程”博客

Basically you create your own cancellation '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; 
}

And then use that with a try/catch to call your async function: 然后使用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 
}

Really need to read his blog posting... 真的需要阅读他的博客帖子......

In short... No its not possible to cancel ac# Task that doesn't attempt to observe a CancellationToken, at least not in the context you are referring to. 简而言之......不可能取消不尝试观察CancellationToken的ac#任务,至少在你所指的上下文中是这样。 (ending the app for example, would do it) (例如,结束应用程序,会这样做)

The link here on Cancellation discusses the various patterns on how to leverage a cancellation token but since you are dealing with a library you don't control, there isn't much you can do. Cancellation上的链接讨论了如何利用取消令牌的各种模式,但由于您正在处理一个您无法控制的库,因此您无能为力。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM