C#Threading.Task.Parallel.For中的Bug?
这个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) {
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;
}