.net - Parallel.For 多久调用一次 localInit?

标签 .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);



根据documentation

The localInit delegate is invoked once for each thread that participates in the loop's execution



但是我认为我下面的例子与它相矛盾
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");

它打印一条消息,例如

79 inits between 13 threads



这是怎么回事?

最佳答案

尝试录制任务 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");

这打印

87 inits between 16 threads
87 inits between 87 tasks



文档是错误的。他们应该说

The localInit delegate is invoked once for each task that participates in the loop's execution



可以有比线程更多的任务。总是线程数 ≤ 任务数 ≤ 迭代次数。

关于.net - Parallel.For 多久调用一次 localInit?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51748047/

相关文章:

.net - 在 Linux 中运行 .NET 程序

c# - 任务并行库 - 自定义任务计划程序

c# - 调用 Azure ActiveDirectory 时的任务状态 WaitingForActivation

c# - 使用 Parallel.ForEach 循环时的连接问题

c# - 以并行和顺序方式执行 N 个线程

c# - 下载文件并同时读取

.net - 如何在 Entity Framework 中使用外键作为复合主键的一部分?

java - Thrift TSimpleServer 在多次成功请求后变得无响应

c# - 将 CancellationToken 与异步方法的任务相关联

c# - 在并行处理期间维护 DataTable 行的顺序