【IT168 评论】沿用微软的写法,System.Threading.Tasks.::.Parallel类,提供对并行循环和区域的支持。 我们会用到的方法有For,ForEach,Invoke。
一、简单使用
首先我们初始化一个List用于循环,这里我们循环10次。(后面的代码都会按这个标准进行循环)
Program.Data = new List<int>();
for (int i = 0; i < 10; i++)
{
Data.Add(i);
}
for (int i = 0; i < 10; i++)
{
Data.Add(i);
}
下面我们定义4个方法,分别为for,foreach,并行For,并行ForEach。并测试他们的运行时长。
/// <summary>
/// 是否显示执行过程
/// </summary>
public bool ShowProcessExecution = false;
/// <summary>
/// 这是普通循环for
/// </summary>
private void Demo1()
{
List<int> data = Program.Data;
DateTime dt1 = DateTime.Now;
for (int i = 0; i < data.Count; i++)
{
Thread.Sleep(500);
if (ShowProcessExecution)
Console.WriteLine(data[i]);
}
DateTime dt2 = DateTime.Now;
Console.WriteLine("普通循环For运行时长:{0}毫秒。", (dt2 - dt1).TotalMilliseconds);
}
/// <summary>
/// 这是普通循环foreach
/// </summary>
private void Demo2()
{
List<int> data = Program.Data;
DateTime dt1 = DateTime.Now;
foreach (var i in data)
{
Thread.Sleep(500);
if (ShowProcessExecution)
Console.WriteLine(i);
}
DateTime dt2 = DateTime.Now;
Console.WriteLine("普通循环For运行时长:{0}毫秒。", (dt2 - dt1).TotalMilliseconds);
}
/// <summary>
/// 这是并行计算For
/// </summary>
private void Demo3()
{
List<int> data = Program.Data;
DateTime dt1 = DateTime.Now;
Parallel.For(0, data.Count, (i) =>
{
Thread.Sleep(500);
if (ShowProcessExecution)
Console.WriteLine(data[i]);
});
DateTime dt2 = DateTime.Now;
Console.WriteLine("并行运算For运行时长:{0}毫秒。", (dt2 - dt1).TotalMilliseconds);
}
/// <summary>
/// 这是并行计算ForEach
/// </summary>
private void Demo4()
{
List<int> data = Program.Data;
DateTime dt1 = DateTime.Now;
Parallel.ForEach(data, (i) =>
{
Thread.Sleep(500);
if (ShowProcessExecution)
Console.WriteLine(i);
});
DateTime dt2 = DateTime.Now;
Console.WriteLine("并行运算ForEach运行时长:{0}毫秒。", (dt2 - dt1).TotalMilliseconds);
}
/// 是否显示执行过程
/// </summary>
public bool ShowProcessExecution = false;
/// <summary>
/// 这是普通循环for
/// </summary>
private void Demo1()
{
List<int> data = Program.Data;
DateTime dt1 = DateTime.Now;
for (int i = 0; i < data.Count; i++)
{
Thread.Sleep(500);
if (ShowProcessExecution)
Console.WriteLine(data[i]);
}
DateTime dt2 = DateTime.Now;
Console.WriteLine("普通循环For运行时长:{0}毫秒。", (dt2 - dt1).TotalMilliseconds);
}
/// <summary>
/// 这是普通循环foreach
/// </summary>
private void Demo2()
{
List<int> data = Program.Data;
DateTime dt1 = DateTime.Now;
foreach (var i in data)
{
Thread.Sleep(500);
if (ShowProcessExecution)
Console.WriteLine(i);
}
DateTime dt2 = DateTime.Now;
Console.WriteLine("普通循环For运行时长:{0}毫秒。", (dt2 - dt1).TotalMilliseconds);
}
/// <summary>
/// 这是并行计算For
/// </summary>
private void Demo3()
{
List<int> data = Program.Data;
DateTime dt1 = DateTime.Now;
Parallel.For(0, data.Count, (i) =>
{
Thread.Sleep(500);
if (ShowProcessExecution)
Console.WriteLine(data[i]);
});
DateTime dt2 = DateTime.Now;
Console.WriteLine("并行运算For运行时长:{0}毫秒。", (dt2 - dt1).TotalMilliseconds);
}
/// <summary>
/// 这是并行计算ForEach
/// </summary>
private void Demo4()
{
List<int> data = Program.Data;
DateTime dt1 = DateTime.Now;
Parallel.ForEach(data, (i) =>
{
Thread.Sleep(500);
if (ShowProcessExecution)
Console.WriteLine(i);
});
DateTime dt2 = DateTime.Now;
Console.WriteLine("并行运算ForEach运行时长:{0}毫秒。", (dt2 - dt1).TotalMilliseconds);
}
下面是运行结果:

这里我们可以看出并行循环在执行效率上的优势了。
结论1:在对一个数组内的每一个项做单独处理时,完全可以选择并行循环的方式来提升执行效率。
原理1:并行计算的线程开启是缓步开启的,线程数量1,2,4,8缓步提升。(不详,PLinq最多64个线程,可能这也是64)