原文:5天玩转C#并行和多线程编程 —— 第一天 认识Parallel
有修改。
调用:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
ParallelDemo d = new ParallelDemo();
d.ParallelInvokeMethod();
d.ParallelForMethod();
d.ParallelForMethod2();
d.ParallelForSimpleTest();
d.ParallelForEach();
d.ParallelBreak();
ParallelExceptionDemo exDemo = new ParallelExceptionDemo();
exDemo.ParallelInvokeExceptionMethod();
Console.Read();
}
}
}
实际代码:
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
public class ParallelDemo
{
private Stopwatch stopWatch = new Stopwatch();
public void Run1()
{
Thread.Sleep(1000);
Console.WriteLine("Task 1 is cost 2 sec");
}
public void Run2()
{
Thread.Sleep(2000);
Console.WriteLine("Task 2 is cost 3 sec");
}
public void ParallelInvokeMethod()
{
Console.WriteLine("————— {0} —————", MethodBase.GetCurrentMethod().Name);
stopWatch.Start();
Parallel.Invoke(Run1, Run2);
stopWatch.Stop();
Console.WriteLine("Parallel run " + stopWatch.ElapsedMilliseconds + " ms.");
stopWatch.Restart();
Run1();
Run2();
stopWatch.Stop();
Console.WriteLine("Normal run " + stopWatch.ElapsedMilliseconds + " ms.");
}
public void ParallelForMethod()
{
Console.WriteLine("\n————— {0} —————", MethodBase.GetCurrentMethod().Name);
stopWatch.Start();
for (int i = 0; i < 1000; i++)
{
for (int j = 0; j < 6000; j++)
{
int sum = 0;
sum += i;
}
}
stopWatch.Stop();
Console.WriteLine("NormalFor run " + stopWatch.ElapsedMilliseconds + " ms.");
stopWatch.Reset();
stopWatch.Start();
Parallel.For(0, 1000, item =>
{
for (int j = 0; j < 6000; j++)
{
int sum = 0;
sum += item;
}
});
stopWatch.Stop();
Console.WriteLine("ParallelFor run " + stopWatch.ElapsedMilliseconds + " ms.");
}
public void ParallelForMethod2()
{
Console.WriteLine("\n————— {0} —————", MethodBase.GetCurrentMethod().Name);
var obj = new Object();
long num = 0;
stopWatch.Start();
for (int i = 0; i < 1000; i++)
{
for (int j = 0; j < 6000; j++)
{
//int sum = 0;
//sum += item;
num++;
}
}
stopWatch.Stop();
Console.WriteLine("NormalFor run " + stopWatch.ElapsedMilliseconds + " ms.");
stopWatch.Reset();
stopWatch.Start();
Parallel.For(0, 1000, item =>
{
for (int j = 0; j < 6000; j++)
{
//int sum = 0;
//sum += item;
lock (obj)
{
num++;
}
}
});
stopWatch.Stop();
Console.WriteLine("ParallelFor run " + stopWatch.ElapsedMilliseconds + " ms.");
}
public void ParallelForSimpleTest()
{
Console.WriteLine("\n————— {0} —————", MethodBase.GetCurrentMethod().Name);
Parallel.For(0, 20, i =>
{
Console.Write(i + "\t");
});
}
public void ParallelForEach()
{
Console.WriteLine("\n————— {0} —————", MethodBase.GetCurrentMethod().Name);
List<int> list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
Parallel.ForEach(list, item =>
{
Console.Write(item + "\t");
});
}
public void ParallelBreak()
{
Console.WriteLine("\n————— {0} —————", MethodBase.GetCurrentMethod().Name);
ConcurrentBag<int> bag = new ConcurrentBag<int>();
stopWatch.Start();
Parallel.For(0, 1000, (i, state) =>
{
if (bag.Count == 300)
{
state.Stop();
return;
}
bag.Add(i);
});
stopWatch.Stop();
Console.WriteLine("Bag count is " + bag.Count + ", " + stopWatch.ElapsedMilliseconds);
}
}
public class ParallelExceptionDemo
{
private Stopwatch stopWatch = new Stopwatch();
public void Run1()
{
Thread.Sleep(2000);
Console.WriteLine("Task 1 is cost 2 sec");
throw new Exception("Exception in task 1");
}
public void Run2()
{
Thread.Sleep(3000);
Console.WriteLine("Task 2 is cost 3 sec");
throw new Exception("Exception in task 2");
}
public void ParallelInvokeExceptionMethod()
{
Console.WriteLine("\n————— {0} —————", MethodBase.GetCurrentMethod().Name);
stopWatch.Start();
//普通的Exception并不能获取到异常, 为并行诞生的 AggregateExcepation 才可以获取到一组异常
try
{
Parallel.Invoke(Run1, Run2);
}
catch (AggregateException aex)
{
foreach (var ex in aex.InnerExceptions)
{
Console.WriteLine(ex.Message);
}
}
stopWatch.Stop();
Console.WriteLine("Parallel run " + stopWatch.ElapsedMilliseconds + " ms.");
stopWatch.Reset();
stopWatch.Start();
try
{
Run1();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
try
{
Run2();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
stopWatch.Stop();
Console.WriteLine("Normal run " + stopWatch.ElapsedMilliseconds + " ms.");
}
}
}