一:Task中并行和串行
串行:
for (int i = 0; i < 100; i++)
{
Console.WriteLine(i);
}
并行:
1 | Parallel.For(0, 100, (item) => |
二:Parallel.For的实现结构
1.可以设置指定的线程计算,不需要所有的线程参与计算。
1 | int nNumExpectedWorkers = (parallelOptions.EffectiveMaxConcurrencyLevel == -1) ? PlatformHelper.ProcessorCount : parallelOptions.EffectiveMaxConcurrencyLevel; |
2.分区函数,实现线程并行
1 | RangeManager rangeManager = new RangeManager((long)fromInclusive,(long)toExclusive, 1L, nNumExpectedWorkers); |
分区后,使用 ParallelForReplicatingTask处理线程,这个类继承Task
3.不要在Parallel.For中使用break()或Stop(),或许会给你引入不必要的bug;
ConcurrentStack<int> stack = new ConcurrentStack<int>();
Parallel.For(0, 100, (item,loop) =>
{
Thread.Sleep(100000);
stack.Push(item);
});
Console.WriteLine(string.Join(",", stack));
线程池中开启16个线程,使用了12个线程,还有4个线程是CLR为发生饱和,做备用线程
三.Parallel.For高级重载
Parallel.For解决问题是数组的遍历。
public static ParallelLoopResult For
计算1-100的总和
var totalNums = 0;
Parallel.For(1,100,()=> {
return 0;
},(current,loop,total)=> {
total += (int)current;
return total;
},(total)=> {
Interlocked.Add(ref totalNums,total);
});
Console.WriteLine(totalNums);
结果4950
四:Parallel.Foreach()
Parallel.Foreach()应对一些集合运算【非数组】
Dictionary<int, int> dic = new Dictionary<int, int>() {
{ 1, 100 }, { 2, 200 }, { 3, 300 } };
Parallel.ForEach(dic,(item)=> {
Console.WriteLine(item.Key+":"+item.Value);
});
上面是源码,分区函数,首先得分区。
五:Parallel.Invoke()
Parallel.Invoke(() =>
{
Console.WriteLine("我是并行计算{0}",Thread.CurrentThread.ManagedThreadId);
}, () =>
{
Console.WriteLine("我是并行计算{0}", Thread.CurrentThread.ManagedThreadId);
}, () =>
{
Console.WriteLine("我是并行计算{0}", Thread.CurrentThread.ManagedThreadId);
});
Parallel.Invoke()可以同时开始多个线程并行执行,CPU回分配不同的线程执行任务。