40

I have a token for various tasks and I need to better manage their cancellation, to be notified of a cancellation I can use:

token.Register(RegisterMethod);

How can I remove this "subscription"? Is there any way to "UnRegister"?

I thought about doing a workaround with TaskCompletionSource. But I do not know if it would work well. What is the best way to solve this approach?

i3arnon
  • 113,022
  • 33
  • 324
  • 344
J. Lennon
  • 3,311
  • 4
  • 33
  • 64
  • will either of these 2 links help you http://social.msdn.microsoft.com/Forums/en-US/parallelextensions/thread/c2f614f6-c96c-4821-84cc-050b21aaee45 http://stackoverflow.com/questions/5299903/cancellationtokensource-cancelfalse – MethodMan Dec 13 '12 at 16:52
  • it helps but does not solve my problem. – J. Lennon Dec 13 '12 at 16:57

3 Answers3

89

CancellationToken.Register returns a CancellationTokenRegistration instance. If you call Dispose on that instance, your registration will be removed.

Richard Deeming
  • 29,830
  • 10
  • 79
  • 151
2

You can safely dispose the entire CancellationTokenSource. Without worry about unregister callbacks.

Code: https://github.com/microsoft/referencesource/blob/master/mscorlib/system/threading/CancellationTokenSource.cs#L552

The Dispose() method of the CancellationTokenSource will call dispose on every registered callback you added into your Token via Token.Register(callBack).

-6

There is no way to really undo a registration. While the dispose method will remove the callback the token still contains the information that there is a registration:

var cancellationTokenSource = new CancellationTokenSource();

basicTask = Task.Factory.StartNew(() => {
 for (;;) {
  var z = DateTime.Today.ToString();
 }
}, cancellationTokenSource.Token);

var basicTask2 = Task.Factory.StartNew(() => {
 for (;;) {
  var z = DateTime.Today.ToString();
 }
}, cancellationTokenSource.Token);

//var usingThisCodeWillResultInADeadlock = cancellationTokenSource.Token.Register(() => { });
//usingThisCodeWillResultInADeadlock.Dispose();
cancellationTokenSource.Cancel();
basicTask.Wait();

Disabling the comments will result in a deadlock.

Frank van Wijk
  • 3,234
  • 20
  • 41
  • 5
    I am not sure what you wanted to show -- your `basicTask2` is unused, your `basicTask` has infinite loop inside, so no matter what you cannot stop it or cancel it, and you wait for that task which (by definition) never ends. Uncommenting those 2 lines does not change a thing. – greenoldman Oct 07 '16 at 10:36
  • 1
    You must be joking. Have you misread the question, or have you never looked what CancellationToken.Register returns? – quetzalcoatl Apr 23 '20 at 13:30