我一直在尝试Parallel.For。特别是支持线程本地数据的重载,例如
公共静态System.Threading.Tasks.ParallelLoopResult For(长fromInclusive,长toExclusive,System.Threading.Tasks.ParallelOptions parallelOptions,Func localInit,Func主体,Action localFinally);
为参与循环执行的每个线程调用一次localInit委托
但是我认为下面的例子与之矛盾
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");
它打印一条消息,例如
13个线程之间的79个初始化
这是怎么回事?
答案 0 :(得分:2)
尝试记录任务ID Task.CurrentId
而不是线程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");
此打印
16个线程之间的87个初始化
87个任务之间的87个初始化
该文档是错误的。他们应该改为
对参与循环执行的每个任务一次调用一次localInit委托
任务可能多于线程。总是线程数≤任务数≤迭代数。