这是一些示例测试应用程序,我试图学习Parallel.Foreach循环功能
static void Main(string[] args)
{
List<string> Months = new List<string>()
{
"Jan", "Feb", "Mar", "Apr", "May", "June"
};
Parallel.ForEach(Months, (x) => ProcessRandom(x));
Console.ReadLine();
}
public static void ProcessRandom(string s)
{
Random r = new Random();
int i = r.Next(1, 100);
Thread.Sleep(1000);
Console.WriteLine(string.Format("Month Name {0} and Random ID assigned {1}", s, i));
}
我对foreach的并行理解是它将使用列表中的参数并行运行ProcessRandom方法。该方法中的所有变量都是独立的,它们将彼此独立运行。但是当我运行时,我看到存储在整数'i'中的随机值对于来自月份列表的一对企业显示相同,而一个或可能是2将具有不同的随机值。为什么这样做呢?并行循环不应为每次迭代创建新的随机值。如果我使用parallelOptions并将Parallelism的MaxDegree设置为1,那么我在变量'i'中看到不同的值
请指导我理解并行循环。
答案 0 :(得分:2)
这是因为Random不是随机的而是伪随机的(http://msdn.microsoft.com/en-us/library/system.random.aspx)。 MSDN文章的评论中提到了这个确切的问题。当同时创建多个实例并且在两个实例上调用.Next()时,它们最终可能会得到相同的结果(由于有限的系统时钟分辨率)。为了解决这个问题,我们应该为每次迭代创建一个独特的种子。为此你可以做这样的事情(但有很多方法可以给这只猫做皮肤):
static void Main(string[] args)
{
List<string> Months = new List<string>() { "Jan", "Feb", "Mar", "Apr", "May", "June" };
Parallel.ForEach(Months, (x) => ProcessRandom(x));
Console.ReadLine();
}
public static void ProcessRandom(string s)
{
Random r = new Random(s.GetHashCode());
int i = r.Next(1, 100);
Thread.Sleep(1000);
Console.WriteLine(string.Format("Month Name {0} and Random ID assigned {1}", s, i));
}
**请注意,此示例不保证唯一性,但仅作为生成种子值的方式显示**