I'm using CancellationTokenSource
for timeout purposes most of the time. To avoid forgetting dispose
, when I'm done with the CancellationTokenSource
, I'm using a using
statement. But before the end of the using
statement, I'm always doing a CancellationTokenSource.Cancel()
.
Is it necessary to cancel CancellationTokenSource
before disposal if the cancellation hasn't been used?
Here is an example of code where I'm doing this.
using (CancellationTokenSource TokenSource = new CancellationTokenSource(nTimeout * 1000))
{
for (int i = 0; i < nLoop; i++)
{
if (TokenSource.Token.IsCancellationRequested)
{
bSuccess = false;
break;
}
await Task.Delay(cDelay);
// do some work
}
TokenSource.Cancel();
}
After a CancellationTokenSource
has been disposed tokens based on this source may throw ObjectDisposedException
so you should not use CancellationTokenSource.Token
after the source has been disposed. Fortunately, I don't see this happening in your code.
When you cancel a CancellationTokenSource
it changes state and notifies callbacks that have been registered for the token. However, when your code is about to dispose the CancellationTokenSource
you are already done using the token and there is no need to cancel it.
So in your case it is not necessary to cancel the CancellationTokenSource
before disposing it. However, your use case is somewhat special. When you have a background task you should wait for the task to complete before disposing the source (as stated in my initial paragraph):
using (var cts = new CancellationTokenSource()) {
var task = Task.Run(() => DoSomething(cts.Token));
// Cancel cts or let it cancel itself based on a timeout.
// Then wait for the task to end.
await task;
}