这是Partitioner.Create(int fromInclusive,int toExclusive)中的错误吗?

The*_*ias 3 .net c# partitioning task-parallel-library

我想我发现了该方法中的一个错误Partitioner.Create(int fromInclusive, int toExclusive)rangeSize当范围超过时,它将为未提供的参数计算负值Int32.MaxValue。这是演示该问题的代码示例:

var partitioner = Partitioner.Create(-1, Int32.MaxValue);
var partitions = partitioner.GetPartitions(1);
foreach (var partition in partitions)
{
    while (partition.MoveNext())
    {
        var range = partition.Current;
        Console.WriteLine($"Range: {range.Item1,11} => {range.Item2,11}");
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

Range:          -1 =>  -178956971
Range:  -178956971 =>  -357913941
Range:  -357913941 =>  -536870911
Range:  -536870911 =>  -715827881
Range:  -715827881 =>  -894784851
Range:  -894784851 => -1073741821
Range: -1073741821 => -1252698791
Range: -1252698791 => -1431655761
Range: -1431655761 => -1610612731
Range: -1610612731 => -1789569701
Range: -1789569701 => -1968526671
Range: -1968526671 => -2147483641
Range: -2147483641 =>  2147483647
Run Code Online (Sandbox Code Playgroud)

因此,循环使用这些范围for (int i = range.Item1; i < range.Item2; i++)将导致除最后一个范围以外的所有范围零循环,这将有效地循环该Int32类型的整个范围。

有一个特例。下面的分区程序计算的a rangeSize为1。

Partitioner.Create(Int32.MinValue, Int32.MaxValue);
Run Code Online (Sandbox Code Playgroud)

这是该方法的源代码

public static OrderablePartitioner<Tuple<int, int>> Create(
    int fromInclusive, int toExclusive)
{
    // How many chunks do we want to divide the range into?  If this is 1, then the
    // answer is "one chunk per core".  Generally, though, you'll achieve better
    // load balancing on a busy system if you make it higher than 1.
    int coreOversubscriptionRate = 3;

    if (toExclusive <= fromInclusive) throw new ArgumentOutOfRangeException("toExclusive");
    int rangeSize = (toExclusive - fromInclusive) /
        (PlatformHelper.ProcessorCount * coreOversubscriptionRate);
    if (rangeSize == 0) rangeSize = 1;
    return Partitioner.Create(CreateRanges(fromInclusive, toExclusive, rangeSize),
        EnumerablePartitionerOptions.NoBuffering); // chunk one range at a time
}
Run Code Online (Sandbox Code Playgroud)

减法似乎发生了整数溢出toExclusive - fromInclusive

如果这确实是一个错误,那么您建议什么解决方法,直到在.NET Framework的将来版本中修复该问题为止?

mjw*_*lls 5

似乎在toExclusive-fromInclusive的除法上发生整数溢出。

是的,看起来像是个错误。

在.NET Framework的将来版本中修复之前,您建议采取什么解决方法?

我建议您铸造输入,long并调用该版本代替。它仍然具有类似的溢出错误,但是如果您的原始输入是int绝对不会出现的溢出情况long