C#Threading.Task.Parallel.For中的Bug?

C#Threading.Task.Parallel.For中的Bug?,c#,parallel-processing,task-parallel-library,C#,Parallel Processing,Task Parallel Library,这个bug是并行的吗 public class DataPoint { public int Game { get; set; } public byte Card { get; set; } public byte Location { get; set; } public DataPoint(int g,byte c,byte Loc) {

这个bug是并行的吗

   public class DataPoint
        {
            public int Game { get; set; }
            public byte Card { get; set; }
            public byte Location { get; set; }
            public DataPoint(int g,byte c,byte Loc)
            {
                Game = g;
                Card = c;
                Location = Loc;
            }
            public override string ToString()
            {
                return String.Format("{0} {1} {2}",Game,Card,Location);
            }
        }
这一定是一个并行的bug

private static System.Collections.Concurrent.ConcurrentBag<DataPoint> FillData()
    {
        var points = new System.Collections.Concurrent.ConcurrentBag<DataPoint>();
        long c = 32768;
        long z = 0;
        Parallel.For(z, c, (i) =>
        {
            points.Add(new DataPoint( rand.Next(1, 100001),
                                      (byte)rand.Next(1, 144),
                                      (byte)rand.Next(1, 40)));
            });
        return points;
    }
private static System.Collections.Concurrent.ConcurrentBag FillData()文件
{
var points=new System.Collections.Concurrent.ConcurrentBag();
长c=32768;
长z=0;
对于(z,c,(i)=>
{
添加(新数据点(兰特下一步(100001)),
(字节)rand.Next(1144),
(字节)rand.Next(1,40));
});
返回点;
}
工作

private static System.Collections.Concurrent.ConcurrentBag FillData()文件
{
var points=new System.Collections.Concurrent.ConcurrentBag();
长c=32769;
长z=0;
对于(z,c,(i)=>
{
添加(新数据点(兰特下一步(100001)),
(字节)rand.Next(1144),
(字节)rand.Next(1,40));
});
返回点;
}

不是每个都默认为{1,1,1}

在多线程情况下,随机数永远都不好


阅读:

随机类被明确记录为非线程安全类

你在错误的地点和时间以错误的方式使用了错误的课程

图书馆里没有bug

编辑 这里的简单解决方案是,
Random()
Parallel.For()
不能很好地结合在一起。只需将Parallel.For替换为正常的
For(;)
循环即可。对于32k元素,您不会注意到差异


如果您仍然希望它并行运行,则必须拆分范围,运行两个任务,并为每个任务提供自己的随机实例

这是一位微软公司的员工写的一篇很棒的博文,介绍了在并行循环中处理随机数生成的不同方法及其性能影响:


但是有一个数字,其中is返回所有条目的{1,1,1}。125000如果每个条目都是高度随机的,这是一个问题。你的问题是众所周知的;这就是所谓的“选择未损坏”问题。()也就是说,错误地认为当您在自己的程序中导致错误时,“真正的”错误实际上一定是一个明显的错误,它以某种方式设法在经过良好测试和大量调试的库中发布。当然,有时库和编译器中会出现bug。我已经造成了很多这样的事情。但大多数时候,正确的开始假设是您的代码是错误的。但它仍然回避了一个问题,即是什么机制导致ConcurrentBag中的项目突然更改为相同的值,这对我来说毫无意义,是的。@Adam:它们在添加后不会改变。Daniel A.White:如果是这样,我该如何做好,给出建设性的建议,而不仅仅是评论。(否则我将如何改进?)文档中说如果是共享的,就是共享的。@Adam:你问过TPL中是否有bug。答案是:不。如果你想要更具建设性的答案,问一个更好的问题。很抱歉对你挑剔,但请想想Q+A是如何工作的。为什么?什么是更好的问题?。在某个值上(代码将生成一个集合,其中包含每个条目{1,1,1},但它不会包含一个较小的值。您能看到这如何被解释为并行错误吗?对于方法?@Henk:对。使用InterlockedCrement在每个任务上生成种子并构造Random()使用II结果。从委托外部随机设置递增值的初始值。我猜什么时候开始使用Parallel。不管怎样,人们都希望知道如何解决此类问题,或者可能我期望太高了……我向您保证库中有一个bug。只是这不是它。@Eric:只要它只是一个,我就不会我们可以接受。
private static System.Collections.Concurrent.ConcurrentBag<DataPoint> FillData()
    {
        var points = new System.Collections.Concurrent.ConcurrentBag<DataPoint>();
        long c = 32769;
        long z = 0;
        Parallel.For(z, c, (i) =>
        {
            points.Add(new DataPoint( rand.Next(1, 100001),
                                      (byte)rand.Next(1, 144),
                                      (byte)rand.Next(1, 40)));
            });
        return points;
    }