C#编程(六十四)

时间:2022-04-23 02:09:47

在Parallel下面有三个常用的方法Invoke,For,ForEach

Parallel.Invoke()方法是最简单,最简洁的将串行的代码并行化.

在这里先说一点,就是Stopwatch的使用,Stopwatch到底是个什么东西,首先Stopwatch在命名空间System.Diagnostics中.

使用方法如下:

var StopWatch =new Stopwatch();//创建一个Stopwatch实例

StopWatch.Start();//开始计时

StopWatch.Stop();//停止计时

StopWatch.Reset();//重置StopWatch

StopWatch.Restart();//重启被停止的Stopwatch

stopWatch.ElapsedMilliseconds //获取stopWatch从开始到现在的时间差,单位是毫秒

案例:

using System;

using System.Collections.Concurrent;

using System.Collections.Generic;

using System.Diagnostics;

using System.Linq;

using System.Text;

using System.Threading;

using System.Threading.Tasks;

namespace 并行集合和LINQ

{

class Program

{              

static void Main(string[] args)

{

Custom custom = new Custom();

custom.ParallelInvokeMethod();

Console.WriteLine("运行完成");

Console.ReadKey();

}

}

public class Custom

{

private Stopwatch stopWatch = new Stopwatch();

public void Run1()

{

Thread.Sleep(2000);//Thread需要添加命名空间

Console.WriteLine("Task 1 is cost 2 sec");

}

public void Run2()

{

Thread.Sleep(3000);

Console.WriteLine("Task 2 is cost 3 sec");

}

public void ParallelInvokeMethod()

{

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.");//这是正常情况

}

}

}

分析:正确情况下确实应该是5秒左右,明明白白写着呢,3000+2000=5000ms,而使用了Parallel.Invoke方法只用了3秒,由此可见并行执行提高了很多效率.

扩展2:Parallel.For

这个方法和For循环的功能类似,案例:

using System;

using System.Collections.Generic;

using System.Diagnostics;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

namespace 并行扩展

{

class Program

{

static void Main(string[] args)

{

Stopwatch stopWatch = new Stopwatch();

stopWatch.Start();

for (int i = 0; i < 10000; i++)

{

for (int j = 0; j < 60000; j++)

{

int sum = 0;

sum += i;

}

}

stopWatch.Stop();

Console.WriteLine("NormalFor run " + stopWatch.ElapsedMilliseconds + " ms.");

stopWatch.Reset();

stopWatch.Start();

Parallel.For(0, 10000, item =>

{

for (int j = 0; j < 60000; j++)

{

int sum = 0;

sum += item;

}

});

stopWatch.Stop();

Console.WriteLine("ParallelFor run " + stopWatch.ElapsedMilliseconds + " ms.");

Console.WriteLine("运行完毕");

Console.ReadKey();

}

}

}

分析:写了两个循环,做些无用的操作,主要是消耗CPU的资源,通过多次运行结果可以看到们使用了Parallel.For所有的时间差不多也就是单纯for时间的三分之一.是不是在任何时候Parallel.For在任何时候都比这普通的for快呢,肯定不是啊,要是这样的话,C#的for早就淘汰了.

案例:修改代码,添加一个全局变量num

using System;

using System.Collections.Concurrent;

using System.Collections.Generic;

using System.Diagnostics;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

namespace 并行扩展

{

class Program

{

static void Main(string[] args)

{

Stopwatch stopWatch = new Stopwatch();

var obj = new Object();

long num = 0;

ConcurrentBag<long> bag = new ConcurrentBag<long>();

stopWatch.Start();

for (int i = 0; i < 10000; i++)

{

for (int j = 0; j < 60000; j++)

{

//int sum = 0;

//sum += item;

num++;

}

}

stopWatch.Stop();

Console.WriteLine("NormalFor run " + stopWatch.ElapsedMilliseconds + " ms.");

stopWatch.Reset();

stopWatch.Start();

Parallel.For(0, 10000, item =>

{

for (int j = 0; j < 60000; j++)

{

//int sum = 0;

//sum += item;

lock (obj)

{

num++;

}

}

});

stopWatch.Stop();

Console.WriteLine("ParallelFor run " + stopWatch.ElapsedMilliseconds + " ms.");

//并行的问题,需要多运行几遍,一遍两遍看不出什么东西来

Console.WriteLine("运行完毕");

Console.ReadKey();            

}

}

}