Introduction

It's a normal situation when you need to control execution of parallel threads but don't want (or can't) pass additional arguments like
CancellationTokenSource or similar objects into your code. This article describes
a simple solution that allows to associate a cancellation token like object with
a thread.

Background

For example let's imagine that you have some IAlgorithm interface like this one:

publicinterface IAlgorithm
{
void PrepareData(Func<object> func);
}

and you need some ability to stop execution of your function that you are passing as argument to PrepareData:

To pass CancellationTokenSource into MyFunctionToPrepareData you, obviously, have to change IAlgorithm and add one more parameter to
the MyFunctionToPrepareData function. That is not always possible.
It'll look like this:

As you can see this class allows to associate one or more CancellationScope instances with
the current thread.
So now everything that you need to check if the cancellation has been requested by
the main flow is to call the CancellationScope.TryContinue() static function
at some checkpoints. It'll get all CancellationScope instances associated with
the current thread, and check the IsCancellationRequested property
of these instances. To cancel a background task from your foreground code it's enough to call
the myCurrentScope.Cancel() method.

Now the MyFunctionToPrepareData function supports the cancellation without any additional arguments:

Its a great little abstraction to not have your code intermingled and dependent on CancelletationTokenSource.

There are few cons too like the hammer called Thread.Abort (which may cancel other tasks as well). But depending on one's situation, this may be a clean way of cancelling a task (or the thread rather).

Not really a good idea. First, Thread.Abort shouldn't really be called. How you've used it is technically safe (called on Current thread), but without explaining why it's safe it is better IMHO to simply not use it in articles like this. Second, the heavyweight implementation for associating the CancellationScope with the thread is not needed, since we have thread local storage (see Thread.AllocateDataSlot). Finally, I'm a firm believer that cancellation requires cooperation on both sides. By using TLS concepts here you've hidden the requirement for cooperation making it much more likely that consuming code will do the wrong thing.