Skip to content

Instantly share code, notes, and snippets.

@dazfuller
Created September 23, 2011 10:00
Show Gist options
  • Save dazfuller/1237064 to your computer and use it in GitHub Desktop.
Save dazfuller/1237064 to your computer and use it in GitHub Desktop.
Some examples using Parallelism in .NET 4
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
namespace PLinqDemo
{
class Demo
{
private IEnumerable<int>_numRange = Enumerable.Range(1, 500);
public void RunDemo()
{
Console.WriteLine("Running Demo");
TaskDemo(); Console.WriteLine();
ParallelForAllDemo(); Console.WriteLine();
ParallelForEachDemo(); Console.WriteLine();
SerialForEachDemo(); Console.WriteLine();
ParallelLinqDemo(); Console.WriteLine();
SerialLinqDemo(); Console.WriteLine();
}
/// <summary>
/// Runs the demo methods
/// </summary>
private void TaskDemo()
{
Task<int> t = new Task<int>(GuessNumber, 8861102);
Console.WriteLine("About to start task");
t.Start();
Console.WriteLine("Task has started");
while (false == t.IsCompleted)
{
Console.WriteLine("Waiting for result");
Thread.Sleep(50);
}
Console.WriteLine("It took {0} attempt(s) to guess the number ", t.Result);
Console.WriteLine("Task completed");
}
/// <summary>
/// Runs a Parallel.ForAll on the number collection, this should be the fastest
/// of all three for-each/all demos as there is no final aggregation
/// </summary>
private void ParallelForAllDemo()
{
Stopwatch sw = new Stopwatch();
sw.Start();
_numRange.AsParallel().ForAll((n) => { Console.Write("{0} ", n); LongTask(); });
sw.Stop();
Console.WriteLine("\n\nRunning a parallel for-all loop took {0} milliseconds\n\n", sw.ElapsedMilliseconds);
}
/// <summary>
/// Runs a Parallel.ForEach on the number collection, this should be slower than
/// a for-all but faster than the serial version as the processing is happening
/// using all available cores. Note, on single core machines there should be
/// no difference in speed
/// </summary>
private void ParallelForEachDemo()
{
Stopwatch sw = new Stopwatch();
sw.Start();
Parallel.ForEach(_numRange, (n) => { Console.Write("{0} ", n); LongTask(); });
sw.Stop();
Console.WriteLine("\n\nRunning a parallel for-each loop took {0} milliseconds\n\n", sw.ElapsedMilliseconds);
}
/// <summary>
/// Runs a standard foreach on the number collection, this should be the slowest
/// of all the for-each/all demos except on single-core, single-processor machines
/// </summary>
private void SerialForEachDemo()
{
Stopwatch sw = new Stopwatch();
sw.Start();
foreach (int n in _numRange)
{
Console.Write("{0} ", n);
LongTask();
}
sw.Stop();
Console.WriteLine("\n\nRunning a standard, serial for-each loop took {0} milliseconds", sw.ElapsedMilliseconds);
}
/// <summary>
/// This is an example of using Parallel LINQ, this should be slower or of equal
/// speed to the standard serial LINQ example as there is no processing involved in
/// selecting an element. If the "AsSequential" method is removed then this can be
/// slower as the items are not accessed in a sequential manner and so collection of
/// the values matching the criteria will be slower. Thread safety will also
/// provide a bottle neck
/// </summary>
private void ParallelLinqDemo()
{
Console.WriteLine("Using PLINQ to determine the average of the values between 100 and 200");
Stopwatch sw = new Stopwatch();
sw.Start();
double result = (from n in _numRange.AsParallel().AsSequential()
where n >= 300 && n <= 400
select n).Average();
sw.Stop();
Console.WriteLine("Calculating the average value of {0} took {1} milliseconds", result, sw.ElapsedMilliseconds);
}
/// <summary>
/// An example of using LINQ to find all values matching a criteria from a collection
/// </summary>
private void SerialLinqDemo()
{
Console.WriteLine("Using LINQ to determine the average of the values between 300 and 400");
Stopwatch sw = new Stopwatch();
sw.Start();
double result = (from n in _numRange
where n >= 300 && n <= 400
select n).Average();
sw.Stop();
Console.WriteLine("Calculating the average value of {0} took {1} milliseconds", result, sw.ElapsedMilliseconds);
}
/// <summary>
/// Method to perform a task
/// </summary>
/// <param name="o">Object state</param>
/// <returns>Number of guesses taken</returns>
public int GuessNumber(object o)
{
int value = Convert.ToInt32(o);
int upperBound = value * 2;
Random rand = new Random();
int count = 1;
while (rand.Next(upperBound) != value)
{
count++;
}
return count;
}
/// <summary>
/// Runs a process intensive task numerous times to provide slow down the thread. A
/// Thread.Sleep call could be used instead but will not show much difference in the
/// task manager. Using this method the task manager can be used to show how the load
/// is being split between cores and processors.
/// </summary>
private void LongTask()
{
for (int i = 0; i < 10000; i++)
{
var ms = DateTime.Now.Millisecond;
}
}
}
class Program
{
static void Main(string[] args)
{
// Create a new Demo object and run it's examples
Demo d = new Demo();
d.RunDemo();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment