我制作了这个小程序来测试并行化。
当我多次点击button1时,它会以IndexOutOfBounds异常结束。我想这是因为我的内存不足。为什么我使用并行化而不是常规foreach(按钮2单击)?
private void button1_Click(object sender, EventArgs e)
{
var s = Stopwatch.StartNew();
int[] nums = new int[10000];
List<int> randoms = new List<int>();
Parallel.ForEach(nums, i =>
{
randoms.Add(new Random().Next());
});
s.Stop();
label1.Text = "Added " + randoms.Count() + " randoms in "
+ s.Elapsed.Milliseconds.ToString() + " milliseconds";
}
private void button2_Click(object sender, EventArgs e)
{
var s = Stopwatch.StartNew();
int[] nums = new int[10000];
List<int> randoms = new List<int>();
foreach (var i in nums)
{
randoms.Add(new Random().Next());
}
s.Stop();
label2.Text = "Added " + randoms.Count() + " randoms in "
+ s.Elapsed.Milliseconds.ToString() + " milliseconds";
}
答案 0 :(得分:2)
在Parallel.ForEach
代码中,您同时修改了一个非线程安全的List<int>
。
当您在另一个线程中调整内部数组的大小时,尝试添加到List
的末尾时会发生异常。
相反,您应该使用ConcurrentBag
或ConcurrentQueue
答案 1 :(得分:2)
您正在并行修改randoms
。这是一个错误,因为列表对于并发添加是不安全的。
此外,IndexOutOfBounds与内存不足无关。您可以通过仔细查看异常来找到所有这些:消息告诉您它不是OOM。堆栈跟踪告诉您错误发生在哪一行(它位于Add
- 行,对吧?)。