Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I kill all threads spawned by Parallel.ForEach from my main thread?

Here's the scenario:

I have a Windows Service that's running. OnStart() it sets up a timer that will call a function (let's call it ProcessEvent()). The code inside ProcessEvent is a critical section, so only one thread can do the following:

private void ProcessEvent(object sender, ElapsedEventArgs e)
{
    lock(lockObj)
    {
        string[] list = GetList();
        Parallel.ForEach(list, item => { ProcessItem(item) });
    }
}

ProcessItem can potentially take a long time.

Now when the service is stopped my OnStop() currently just stops and disposes the timer. However I noticed that even after service is stopped there are threads that are still running ProcessItem().

So how can I kill all running threads spawned by this program (mainly the ones spawned by the Parallel.ForEach but also any that are waiting on the lock in ProcessEvent)?

I know that had I created the thread myself I could set isBackground to true and it will all get killed when process dies but I don't create these threads manually.

like image 255
encee Avatar asked Dec 13 '22 13:12

encee


1 Answers

Use the CancellationToken structure. Read this and this for more information.

// Setup the cancellation mechanism.
var cts = new CancellationTokenSource();
var po = new ParallelOptions();
po.CancellationToken = cts.Token;

// Run the enumerator in parallel.
Parallel.ForEach(list, po, 
  (item) =>
  {
    ProcessItem(item);
    po.CancellationToken.ThrowIfCancellationRequested();
  });

// Call Cancel to make Parallel.ForEach throw.
// Obviously this must done from another thread.
cts.Cancel();
like image 61
Brian Gideon Avatar answered Dec 28 '22 08:12

Brian Gideon