I've been experimenting with Parallel.For. In particular, overloads that support thread-local data such as
public static System.Threading.Tasks.ParallelLoopResult For (long fromInclusive, long toExclusive, System.Threading.Tasks.ParallelOptions parallelOptions, Func localInit, Func body, Action localFinally);
According to the documentation
The localInit delegate is invoked once for each thread that participates in the loop's execution
However I think my example below contradicts it
var threads = new ConcurrentBag<int>();
ValueTuple LocalInit()
{
threads.Add(Thread.CurrentThread.ManagedThreadId);
return new System.ValueTuple();
}
ValueTuple Body(long i, ParallelLoopState _, ValueTuple state)
{
Thread.Sleep(100);
return state;
}
void LocalFinally(ValueTuple state) { };
Parallel.For(0L, 1000L, new ParallelOptions(), LocalInit, Body, LocalFinally);
Console.WriteLine($"{threads.Count} inits between {threads.Distinct().Count()} threads");
It prints a message such as
79 inits between 13 threads
What's going on?
Try recording task id Task.CurrentId
instead of thread id.
var threads = new ConcurrentBag<int>();
var tasks = new ConcurrentBag<int>();
ValueTuple LocalInit()
{
threads.Add(Thread.CurrentThread.ManagedThreadId);
tasks.Add(Task.CurrentId ?? throw new Exception());
return new System.ValueTuple();
}
ValueTuple Body(long i, ParallelLoopState _, ValueTuple state)
{
Thread.Sleep(100);
return state;
}
void LocalFinally(ValueTuple state) { };
Parallel.For(0L, 1000L, new ParallelOptions(), LocalInit, Body, LocalFinally);
Console.WriteLine($"{threads.Count} inits between {threads.Distinct().Count()} threads");
Console.WriteLine($"{tasks.Count} inits between {tasks.Distinct().Count()} tasks");
This prints
87 inits between 16 threads
87 inits between 87 tasks
The docs are wrong. They should instead say
The localInit delegate is invoked once for each task that participates in the loop's execution
There can be more tasks than threads. Always number of threads ≤ number of tasks ≤ number of iterations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With