Is the correct way to cancel a cancellation token used in a task?

In general I see a fair use of Cancel Token in your code, but according the Task Async Pattern your code could be not cancelling immediately.

while (!ct.IsCancellationRequested)
{
   App.viewablePhrases = App.DB.GetViewablePhrases(Settings.Mode, Settings.Pts);
   await CheckAvailability();   //Your Code could be blocked here, unable to cancel
}

For responding right away, the blocking code also should be cancelled

await CheckAvailability(ct);   //Your blocking code in the loop also should be stoped

It is up to you if you must Dispose, if there are many memory resources been reserved in the interrupted code, you should do it.


CancellationTokenSource.Cancel() is a valid way to start cancellation.

Polling ct.IsCancellationRequested avoids throwing OperationCanceledException. Because its polling, it requires an iteration of the loop to complete before it will respond to the cancellation request.

If GetViewablePhrases() and CheckAvailability() can be modified to accept a CancellationToken, this may make cancellation faster to respond, at the cost of having OperationCanceledException thrown.

"should I be doing a cts.Dispose()?" is not that straightforward...

"Always dispose IDisposables ASAP"

Is more of a guideline than a rule. Task itself is disposable, yet hardly ever directly disposed in code.

There are cases (when WaitHandle or cancellation callback handlers are used) where disposing cts would free a resource / remove a GC root which otherwise would only be freed by a Finalizer. These don't apply to your code as it stands but may in future.

Adding a call to Dispose after cancelling would guarantee that these resources are freed promptly in future versions of the code.

However, you'd have to either wait for the code that uses cts to finish before calling dispose, or modify the code to deal with ObjectDisposedException from use of cts (or its token) after disposal.