I'm using the Parallel.ForEach loop to do some work and I initialize it with the localInit like this:
localInit: () => new { foo = new Foo(), bars = CreateBars(), } According to the documentation:
localInit, or the function that initializes the thread-local variable. This function is called once for each partition in which theParallel.ForEach<TSource>operation executes. Our example initializes the thread-local variable to zero.
So I tried to use it like that but I observed that the loop is constantly killing and creating new tasks which results in frequent calls to localInit. This I my option is counterproductive and doesn't work as desired.
I thought when the Parallel.ForEach would create for example four partitions it would keep them alive until it itereated over all items but it doesn't. It's calling localFinally and localInit several hundered times for a collection with a few thousend items. How so?
Can this behavior somehow be prevented? I was really hoping to save some resources but it doesn't really let me.
Here's how the loop looks like:
var parallelLoopResult = Parallel.ForEach ( source: items, parallelOptions: parallelOptions, localInit: () => new { foo = new Foo(), bars = CreateBars(), }, body: (item, loopState, i, local) => { parallelOptions.CancellationToken.ThrowIfCancellationRequested(); var results = local.bars.Select(x => ...).ToList(). .... return local; }, localFinally: local => { local.foo.Dispose(); lock (aggregateLock) { ... process transformed bars } } ); ParallelOptions:
var parallelOptions = new ParallelOptions { CancellationToken = cancellationTokenSource.Token, #if DEBUG MaxDegreeOfParallelism = 1 //MaxDegreeOfParallelism = Environment.ProcessorCount #else MaxDegreeOfParallelism = Environment.ProcessorCount #endif };
source(IEnumerable<T>orPartitioner<T>)? What are yourParallelOptions?