Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CancellationToken Cancel not breaking out of BlockingCollection

I have a cancellation token like so

   static CancellationTokenSource TokenSource= new CancellationTokenSource();

I have a blocking collection like so

BlockingCollection<object> items= new BlockingCollection<object>();

var item = items.Take(TokenSource.Token);

if(TokenSource.CancelPending)
   return;

When I call

TokenSource.Cancel();

The Take does not continue like it should. If I use the TryTake with a poll the Token shows it is being set as Canceled.

like image 851
Kenoyer130 Avatar asked Apr 22 '11 18:04

Kenoyer130


People also ask

How do I cancel a CancellationToken?

A CancellationToken can only be created by creating a new instance of CancellationTokenSource . CancellationToken is immutable and must be canceled by calling CancellationTokenSource. cancel() on the CancellationTokenSource that creates it. It can only be canceled once.

Can I reuse CancellationTokenSource?

Therefore, cancellation tokens cannot be reused after they have been canceled. If you require an object cancellation mechanism, you can base it on the operation cancellation mechanism by calling the CancellationToken.

What is cancellation token source?

A CancellationTokenSource object, which provides a cancellation token through its Token property and sends a cancellation message by calling its Cancel or CancelAfter method. A CancellationToken object, which indicates whether cancellation is requested.


1 Answers

That's working as expected. If the operation is canceled, items.Take will throw OperationCanceledException. This code illustrates it:

static void DoIt()
{
    BlockingCollection<int> items = new BlockingCollection<int>();
    CancellationTokenSource src = new CancellationTokenSource();
    ThreadPool.QueueUserWorkItem((s) =>
        {
            Console.WriteLine("Thread started. Waiting for item or cancel.");
            try
            {
                var x = items.Take(src.Token);
                Console.WriteLine("Take operation successful.");
            }
            catch (OperationCanceledException)
            {
                Console.WriteLine("Take operation was canceled. IsCancellationRequested={0}", src.IsCancellationRequested);
            }
        });
    Console.WriteLine("Press ENTER to cancel wait.");
    Console.ReadLine();
    src.Cancel(false);
    Console.WriteLine("Cancel sent. Press Enter when done.");
    Console.ReadLine();
}
like image 149
Jim Mischel Avatar answered Oct 02 '22 01:10

Jim Mischel