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.