我一直在尝试 Parallel.For。特别是,支持线程本地数据的重载,例如
公共静态 System.Threading.Tasks.ParallelLoopResult For (long fromInclusive, long toExclusive, System.Threading.Tasks.ParallelOptions parallelOptions, Func localInit, Func body, Action localFinally);
根据文档 https://learn.microsoft.com/en-gb/dotnet/api/system.threading.tasks.parallel.for?view=netframework-4.7.2#System_Threading_Tasks_Parallel_For__1_System_Int64_System_Int64_System_Threading_Tasks_ParallelOptions_System_Func___0__System_Func_System_Int64_System_Threading_Tasks_ParallelLoopState___0___0__System_Action___0__
对于参与循环执行的每个线程,都会调用一次 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 个初始化
这是怎么回事?
尝试记录任务idTask.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 委托被调用每个任务一次参与循环的执行
任务数量可以多于线程数量。总是线程数 ≤ 任务数量 ≤ 迭代次数.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)