Col*_*nic 5 .net task-parallel-library parallel.foreach
我一直在试验 Parallel.For。特别是支持线程本地数据的重载,例如
public static System.Threading.Tasks.ParallelLoopResult For (long fromInclusive, long toExclusive, System.Threading.Tasks.ParallelOptions parallelOptions, Func localInit, Func body, 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");
Run Code Online (Sandbox Code Playgroud)
它打印一条消息,例如
13 个线程之间的 79 个初始化
这是怎么回事?
尝试记录任务 IDTask.CurrentId而不是线程 ID。
var threads = new ConcurrentBag<int>();\nvar tasks = new ConcurrentBag<int>();\nValueTuple LocalInit()\n{\n threads.Add(Thread.CurrentThread.ManagedThreadId);\n tasks.Add(Task.CurrentId ?? throw new Exception());\n return new System.ValueTuple();\n}\nValueTuple Body(long i, ParallelLoopState _, ValueTuple state) \n{\n Thread.Sleep(100);\n return state;\n}\nvoid LocalFinally(ValueTuple state) { };\n\nParallel.For(0L, 1000L, new ParallelOptions(), LocalInit, Body, LocalFinally);\n\nConsole.WriteLine($"{threads.Count} inits between {threads.Distinct().Count()} threads");\nConsole.WriteLine($"{tasks.Count} inits between {tasks.Distinct().Count()} tasks");\nRun Code Online (Sandbox Code Playgroud)\n\n这打印
\n\n\n\n\n16 个线程之间有 87 个初始化
\n
\n 87 个任务之间有 87 个初始化
文档是错误的。他们应该说
\n\n\n\n\n对于参与循环执行的每个任务,都会调用一次 localInit 委托
\n
任务数量可以多于线程数量。始终是线程数\xe2\x89\xa4任务数\xe2\x89\xa4迭代次数。
\n