Created
April 13, 2010 11:26
-
-
Save ericnel/364522 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.IO; | |
using System.Linq; | |
using System.Text; | |
using System.Threading; | |
using System.Threading.Tasks; | |
namespace ParallelDemos | |
{ | |
class Structured | |
{ | |
// Run comparison of sequential vs parallel code using the TPL | |
#region Comparison Tests | |
internal static void ForEachDemo() | |
{ | |
Program.Compare(ForEachSequential, ForEachParallel, "Compare foreach with Parallel.ForEach"); | |
} | |
internal static void InvokeDemo() | |
{ | |
Program.Compare(SequentialInvoke, ParallelInvoke, "Compare sequential with Parallel.Invoke"); | |
} | |
#endregion | |
// Simple use of Parallel.ForEach | |
#region ForEach | |
static readonly string[] Arr = | |
Directory.GetFiles(@"C:\Users\Public\Pictures\Sample Pictures", "*.jpg"); | |
private static void ForEachSequential() | |
{ | |
foreach (string ip in Arr) | |
{ | |
Program.SimulateProcessing(); | |
Console.WriteLine(ip + TID); | |
if (ip.Contains("Tree")) | |
{ | |
break; | |
} | |
} | |
} | |
private static void ForEachParallel() | |
{ | |
Parallel.ForEach(Arr, (string ip, ParallelLoopState ps) => | |
{ | |
Program.SimulateProcessing(); | |
Console.WriteLine(ip + TID); | |
if (ip.Contains("Tree")) | |
{ | |
ps.Stop(); | |
} | |
}); | |
} | |
#endregion | |
// Simple use of Parallel.Invoke | |
#region Invoke | |
private static void SequentialInvoke() | |
{ | |
DoWork(); | |
DoMoreWork(); | |
DoYetMoreWork(); | |
DoWork(); | |
DoMoreWork(); | |
DoYetMoreWork(); | |
} | |
private static void ParallelInvoke() | |
{ | |
Parallel.Invoke(DoWork, DoMoreWork, DoYetMoreWork, DoWork, DoMoreWork, DoYetMoreWork); | |
} | |
#endregion | |
// Helper methods | |
#region DoWork Helpers | |
private static void DoWork() | |
{ | |
Console.WriteLine("DoingWork " + TID); | |
Program.SimulateProcessing(); | |
} | |
private static void DoMoreWork() | |
{ | |
Console.WriteLine("DoingMoreWork " + TID); | |
Program.SimulateProcessing(); | |
} | |
private static void DoYetMoreWork() | |
{ | |
Console.WriteLine("DoingYetMoreWork" + TID); | |
Program.SimulateProcessing(); | |
} | |
#endregion | |
#region Helpers | |
private static string TID | |
{ | |
get | |
{ | |
return " TID = " + Thread.CurrentThread.ManagedThreadId.ToString(); | |
} | |
} | |
#endregion | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
namespace ParallelDemos | |
{ | |
class PLINQ | |
{ | |
// Run comparison of sequential vs parallel code using the TPL | |
#region Comparison Tests | |
internal static void PLINQDemo() | |
{ | |
Program.Compare(SequentialLinq, ParallelLinq, "Compare sequential LINQ with .AsParallel"); | |
} | |
#endregion | |
// LINQ to Objects using .AsParallel | |
#region LINQ | |
private static void SequentialLinq() | |
{ | |
IEnumerable<int> arr = Enumerable.Range(2, 10000000); | |
var q = from n in arr | |
where IsPrime(n) | |
select n.ToString(); | |
#region Alternative Syntax | |
// var q = arr.Where(n => IsPrime(n)).Select(n => n.ToString()); | |
#endregion | |
Console.WriteLine(q.Count().ToString()); | |
} | |
private static void ParallelLinq() | |
{ | |
IEnumerable<int> arr = Enumerable.Range(2, 10000000); | |
var q = from n in arr.AsParallel() | |
where IsPrime(n) | |
select n.ToString(); | |
#region Alternative Syntax | |
// var q = arr.AsParallel().Where(n => IsPrime(n)).Select(n => n.ToString()); | |
#endregion | |
Console.WriteLine(q.Count().ToString()); | |
} | |
private static bool IsXmasy(int p) | |
{ | |
if (p % 24 == 0) return true; | |
if (p % 25 == 0) return true; | |
return false; | |
} | |
private static bool IsPrime(int p) | |
{ | |
int upperbound = (int)Math.Sqrt(p); | |
for (int i = 2; i <= upperbound; i++) | |
{ | |
if (p % i == 0) return false; | |
} | |
return true; | |
} | |
#endregion | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.Linq; | |
using System.Text; | |
using System.Threading; | |
using System.Threading.Tasks; | |
namespace ParallelDemos | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
//Structured.ForEachDemo(); | |
//Structured.InvokeDemo(); | |
//PLINQ.PLINQDemo(); | |
Tasks.TaskDemo(); | |
// TaskTreeDemo.WalkTreeDemo(); | |
} | |
#region Helpers | |
internal static void SimulateProcessing() | |
{ | |
Thread.SpinWait(100000000); | |
} | |
internal static void Compare(Action sequentialMethod, Action parallelMethod, string description) | |
{ | |
Console.WriteLine("--------------------------------------------"); | |
Console.WriteLine(description); | |
Console.WriteLine("--------------------------------------------"); | |
// Run the sequential code | |
long sequentialMilliseconds = RunCode(sequentialMethod, "Sequential"); | |
// Run the parallel code | |
Console.WriteLine(); | |
long parallelMilliseconds = RunCode(parallelMethod, "Parallel"); | |
double improvement = (double)sequentialMilliseconds / parallelMilliseconds; | |
Console.WriteLine("\nParallel is {0} times faster", Math.Round(improvement, 1)); | |
Console.ReadLine(); | |
} | |
private static long RunCode(Action codeMethod, string description) | |
{ | |
Console.WriteLine("Running {0} code:", description); | |
var sw = Stopwatch.StartNew(); | |
codeMethod(); | |
var durartionMilliseconds = sw.ElapsedMilliseconds; | |
Console.WriteLine("{0} Elapsed = {1}", description, durartionMilliseconds); | |
return durartionMilliseconds; | |
} | |
#endregion | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Threading; | |
using System.Threading.Tasks; | |
namespace ParallelDemos | |
{ | |
class Tasks | |
{ | |
internal static void TaskDemo() | |
{ | |
Console.WriteLine("--------------------------------------------"); | |
Console.WriteLine("Tasks"); | |
Console.WriteLine("--------------------------------------------"); | |
// Create 3 tasks (t1,t2,t3) and start t2 and t3 | |
#region Simple Task Creation | |
Console.WriteLine("==Create t1 but do not start=="); | |
Console.ReadLine(); | |
Task t1 = new Task(() => DoWork("t1")); | |
// Using a TaskFactory | |
var tf = new TaskFactory(TaskCreationOptions.AttachedToParent,TaskContinuationOptions.AttachedToParent ); | |
Console.WriteLine("\n==Create and start t2 and t3=="); | |
Task t2 = tf.StartNew(() => DoWork("t2")); | |
Task t3 = tf.StartNew(() => DoMoreWork("t3")); | |
Console.WriteLine("\nWaiting on t2 and t3 to complete\n"); | |
t2.Wait(); | |
t3.Wait(); | |
Console.WriteLine("\nt2 and t3 have completed"); | |
#endregion | |
// Create a "Pipeline" of Tasks and looks at Task properties | |
#region Pipelines and properties | |
Console.WriteLine("\n==Create a task to continue after t1=="); | |
Console.ReadLine(); | |
t1.ContinueWith(t => Console.WriteLine(">>I'm a Task runing after t1 finishes"), TaskContinuationOptions.OnlyOnRanToCompletion); | |
Console.WriteLine("Task t1 has ID of {0}, status {1}", t1.Id, t1.Status); | |
Console.WriteLine("\nStarting t1"); | |
t1.Start(); | |
Console.WriteLine("\nTask t1 has ID of {0}, status {1}", t1.Id, t1.Status); | |
Thread.Sleep(1000); | |
Console.WriteLine("Task t1 has ID of {0}, status {1}", t1.Id, t1.Status); | |
// Alternative Wait Syntax | |
Console.WriteLine("\nWaiting on t1, t2 and t3 to complete"); | |
Task.WaitAll(t1, t2, t3); | |
Console.WriteLine("\nt1, t2 and t3 have completed"); | |
#endregion | |
// Create a task with child tasks | |
#region Parent and Child Tasks | |
Console.WriteLine("\n==Create t4 which will spawn 5 child tasks=="); | |
Console.ReadLine(); | |
Task t4 = new Task(() => DoYetMoreWork("t4")); | |
t4.ContinueWith(t => Console.WriteLine(">>I'm a Task running after t4 finishes"), TaskContinuationOptions.OnlyOnRanToCompletion); | |
t4.Start(); | |
t4.Wait(); | |
Console.WriteLine("\nt4 completed - but did the children?"); | |
#endregion | |
Console.ReadLine(); | |
// Create a long running task and cancel it | |
#region Cancellation Token | |
Console.WriteLine("\n==Create t5 and start, passing in a cancellation token=="); | |
Console.ReadLine(); | |
var tokenSource = new CancellationTokenSource(); | |
CancellationToken ct = tokenSource.Token; | |
var t5 = Task.Factory.StartNew(() => DoWorkUntilCancelled(ct)); | |
Console.WriteLine("\nDo work while t5 continues to run"); | |
Program.SimulateProcessing(); | |
Program.SimulateProcessing(); | |
Console.WriteLine("\nAttempt to cancel t5"); | |
tokenSource.Cancel(); | |
#endregion | |
Console.ReadLine(); | |
} | |
#region DoWork Helpers | |
private static void DoWork(string taskName) | |
{ | |
Console.WriteLine("DoingWork for Task {0} {1}", taskName, TID ); | |
Program.SimulateProcessing(); | |
} | |
private static void DoMoreWork(string taskName) | |
{ | |
Console.WriteLine("DoingMoreWork for Task {0} {1}", taskName, TID); | |
Program.SimulateProcessing(); | |
} | |
private static void DoYetMoreWork(string taskName) | |
{ | |
Console.WriteLine("DoingYetMoreWork for Task {0} {1}", taskName, TID); | |
Task t1 = new Task(() => DoWork("child t1")); | |
Task t2 = new Task(() => DoWork("child t2")); | |
Task t3 = new Task(() => DoWork("child t3")); | |
Task t4 = new Task(() => DoWork("child t4")); | |
Task t5 = new Task(() => DoWork("child t5")); | |
t1.Start(); | |
t2.Start(); | |
t3.Start(); | |
t4.Start(); | |
t5.Start(); | |
Program.SimulateProcessing(); | |
} | |
private static void DoWorkUntilCancelled(CancellationToken ct) | |
{ | |
bool moreToDo = true; | |
while (moreToDo) | |
{ | |
Console.Write("t5 "); | |
Thread.SpinWait(10000000); | |
// Poll on this property if you have to do | |
// other cleanup before throwing.); | |
if (ct.IsCancellationRequested) | |
{ | |
Console.WriteLine(">>I'm t5 and I'm cancelling"); | |
moreToDo = false; | |
} | |
} | |
} | |
#endregion | |
#region Helpers | |
private static string TID | |
{ | |
get | |
{ | |
return " TID = " + Thread.CurrentThread.ManagedThreadId.ToString(); | |
} | |
} | |
#endregion | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment