I myself had used List.ForEach(Action action) many times believing that it was efficient and that it uses multiple threads. Apparently it does not :). Now that i know that it does not use multiple threads, i can think of one or two good reasons why it may not be doing so but none of those convincing enough.
On the other hand, Parallel.ForEach works as expected and uses machine's available power to the fullest. To test the difference between the two, i used following code:
In the Main method, i wrote the following:
TestClass[] testClasses = new TestClass[10000];
for (int i = 0; i < testClasses.Length; i++)
{
testClasses[i] = new TestClass();
}
Stopwatch watch = new Stopwatch();
watch.Start();
Parallel.ForEach(testClasses, (t) => t.Method1());
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
List list = new List();
list.AddRange(testClasses);
list.ForEach(t => t.Method1());
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds);
You can use process explorer to witness the spawning of multiple threads when Parallel extension is executed.
On the other hand, Parallel.ForEach works as expected and uses machine's available power to the fullest. To test the difference between the two, i used following code:
public partial class TestClass
{
internal void Method1()
{
System.Threading.Thread.Sleep(1);
}
}
In the Main method, i wrote the following:
TestClass[] testClasses = new TestClass[10000];
for (int i = 0; i < testClasses.Length; i++)
{
testClasses[i] = new TestClass();
}
Stopwatch watch = new Stopwatch();
watch.Start();
Parallel.ForEach(testClasses, (t) => t.Method1());
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds);
watch.Reset();
watch.Start();
List
list.AddRange(testClasses);
list.ForEach(t => t.Method1());
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds);
You can use process explorer to witness the spawning of multiple threads when Parallel extension is executed.