How to cancel Actions already in a BlockingCollection<Action>

151 Views Asked by At

I have a simple class that enqueues actions to execute:

BlockingCollection<Action> blockingCollectionOfEvents = new BlockingCollection<Action>();

System.Threading.Thread workerThread;

public EventQueue()
{
    this.workerThread = new Thread(DequeueEvents);
    this.workerThread.Start();
}

public void EnqueueEvent(Action action)
{
    if (this.blockingCollectionOfEvents.IsAddingCompleted == false)
    {
        this.blockingCollectionOfEvents.Add(action);
    }
}

void DequeueEvents()
{
    foreach (Action action in this.blockingCollectionOfEvents.GetConsumingEnumerable())
    {
        action.Invoke();
    }
}

All is working fine.
Now I need to cancel the tasks already inside the BlockingCollection but as these tasks must release an allocated resource, I can't just empty the BlockingCollection.
I need to signal these tasks to execute an alternate code just to free the resource.
What would be the best solution? Send a reference to a "cancel object" that I send also as a parameter to each task? Or is there a better solution?

2

There are 2 best solutions below

0
Pedro Ferreira On BEST ANSWER

I ended up using a static bool and it works, this is the quickest solution so I don't change all my code.

In my EventQueue object:

public volatile static bool bCancelAll = false;

And the client object using it also sends the static bool from EventQueue, so inside the CalculateTask function I can use it to make decisions accordingly:

this.eventQueue.Enqueue(() => CalculateTask(idToProcess, EventQueue.bCancelAll));

To cancel all then I just do:

EventQueue.bCancelAll = true;
0
Dylech30th On

If what you mean is "cancel the running action in the BlockingCollection", the short answer is, you can't, you can't stop a running Action without letting the Action know that it will be canceled, the best thing you can do is to make the cancellation cooperative, that is, associate a handle (or a flag or whatever you'd like to call it) with the Action and checks if the handle is marked as canceled inside the Action, or calls the corresponding callback that associates with the handle when you want to cancel the Action.