取消任务中使用的取消令牌的正确方法是什么?

Ala*_*an2 10 c# xamarin xamarin.forms

我有创建取消令牌的代码

public partial class CardsTabViewModel : BaseViewModel
{
   public CancellationTokenSource cts;

public async Task OnAppearing()
{
   cts = new CancellationTokenSource(); // << runs as part of OnAppearing()
Run Code Online (Sandbox Code Playgroud)

使用它的代码:

await GetCards(cts.Token);


public async Task GetCards(CancellationToken ct)
{
    while (!ct.IsCancellationRequested)
    {
        App.viewablePhrases = App.DB.GetViewablePhrases(Settings.Mode, Settings.Pts);
        await CheckAvailability();
    }
}
Run Code Online (Sandbox Code Playgroud)

以及稍后在用户离开运行上述代码的屏幕时取消此取消令牌的代码:

public void OnDisappearing()
{
   cts.Cancel();
Run Code Online (Sandbox Code Playgroud)

关于取消,这是在任务中使用令牌时取消令牌的正确方法吗?

我特别检查了这个问题:

使用 IsCancellationRequested 属性?

这让我认为我没有以正确的方式或可能导致异常的方式进行取消。

另外,在这种情况下,在我取消之后,我应该执行 cts.Dispose() 吗?

Pet*_*art 2

CancellationTokenSource.Cancel()是开始取消的有效方式。

轮询ct.IsCancellationRequested避免抛出OperationCanceledException。由于它是轮询的,因此需要完成一次循环迭代,然后才能响应取消请求。

如果GetViewablePhrases()CheckAvailability()可以修改为接受 a CancellationToken,这可能会使取消响应更快,但代价是OperationCanceledException抛出。

“我应该执行 cts.Dispose() 吗?” 不是那么简单吗...

“始终尽快处理 IDisposables”

与其说是规则,不如说是指南。 Task它本身是一次性的,但几乎不会直接在代码中处理。

在某些情况下(当WaitHandle使用或取消回调处理程序时),处置cts将释放资源/删除 GC 根,否则只能由终结器释放。这些不适用于您现在的代码,但将来可能会适用。

在取消后添加调用Dispose将保证这些资源在代码的未来版本中立即释放。

但是,您必须等待使用的代码cts在调用 dispose 之前完成,或者修改代码以在处理后处理ObjectDisposedExceptionuse of cts(或其令牌)。