Contrived example, but suppose I have the following in an async method:
var cts = new CancellationTokenSource();
cts.CancelAfter(2000);
cts.Token.Register(Callback);
SomethingThatMightThrow();
await Task.Delay(10000, cts.Token);
This works as expected insofar as after a couple of seconds Callback is called. However, I want to dispose the registration after the Task.Delay
, so suppose I make the following modification:
var cts = new CancellationTokenSource();
cts.CancelAfter(2000);
using (cts.Token.Register(Callback))
{
SomethingThatMightThrow();
await Task.Delay(10000, cts.Token);
}
In this case, Callback is not called, presumably because the exception from the await Task.Delay...
causes the registration to be disposed before it gets invoked.
What's the best way of ensuring both that Callback
gets called on cancellation and that the registration always gets disposed?
I did think of the following, but I'm not sure how robust it is:
var cts = new CancellationTokenSource();
cts.CancelAfter(2000);
var ctr = cts.Token.Register(Callback);
try
{
SomethingThatMightThrow();
await Task.Delay(10000, cts.Token);
}
finally
{
if (!cts.Token.IsCancellationRequested)
ctr.Dispose();
}