0

我做了这个小程序来测试并行化。

当我多次点击 button1 时,它以 IndexOutOfBounds 异常结束。我想这是因为我的内存不足。为什么我通过并行化而不是常规的 foreach(button2 click)得到这个?

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";
}
4

2 回答 2

2

在您的Parallel.ForEach代码中,您正在同时修改一个List<int>不是线程安全的。

当您尝试添加到List内部数组在不同线程中调整大小的末尾时,会发生异常。

相反,您应该使用并发集合,例如ConcurrentBagorConcurrentQueue

于 2012-10-06T20:30:07.737 回答
2

您正在randoms并行修改。这是一个错误,因为该列表对于并发添加是不安全的。

此外,IndexOutOfBounds 与内存不足无关。您可以通过仔细查看异常来找出所有这些:该消息告诉您它不是 OOM。堆栈跟踪会告诉您错误发生在哪一行(它在Add-line 中,对吗?)。

于 2012-10-06T20:30:53.860 回答