Reputation: 1065
I made this small program to test parallelization.
When I hit button1 several times it ends up with an IndexOutOfBounds exception. I guess this is because I run out of memory. Why do I get this with parallelization and not with a regular 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";
}
Upvotes: 0
Views: 219
Reputation: 144206
In your Parallel.ForEach
code, you are concurrently modifying a List<int>
which is not threadsafe.
The exception occurs when you try to add to the end of a List
while the internal array is being resized in a different thread.
Instead you should use a concurrent collection like ConcurrentBag
or ConcurrentQueue
Upvotes: 2
Reputation: 171226
You are modifying randoms
in parallel. That is a bug because the list is not safe for concurrent adding.
Also, IndexOutOfBounds has nothing to do with out-of-memory. You can find out all of this by looking carefully at the exception: The message tells you it is not OOM. And the stack trace tells you in which line the error occured (it was in the Add
-line, right?).
Upvotes: 2