本文主要介绍Parallel.Invoke的使用。
一、使用例子
class ParallelInvoke
{
public void Action1()
{
Thread.Sleep(3000);
Console.WriteLine("in action1");
}
public void Action2()
{
Thread.Sleep(3000);
Console.WriteLine("in action2");
}
public void ParallelAction()
{
Parallel.Invoke(() => Action1(), () => Action2());
}
}
class Program
{
static void Main(string[] args)
{
var stopwatch = Stopwatch.StartNew();
stopwatch.Start();
new ParallelInvoke().ParallelAction();
Console.WriteLine(stopwatch.ElapsedMilliseconds);
Console.Read();
}
}
二、 运行截图
上面的action1和action2如果并行执行至少需要3000*2毫秒,但是使用Invoke,内部并行执行,时间减半。
三、 分析
Parallel.Invoke是最简单的并行编程模型,用于并行执行多个互不相干的方法。有几点需要注意
- 只有当所有的Action执行完成后Invoke才会返回(WaitAll)
- 在执行过程中有其中一个Action发生异常,Invoke不会马上抛出异常,而是等所有的Action完成以后再次抛出异常
四、one more thing
4.1 MaxDegreeOfParallelism
Parallel.Invoke可以通过指定ParallelOption指定最大并行数量。
public void ParallelAction()
{
Parallel.Invoke
(
new ParallelOptions()
{
MaxDegreeOfParallelism = 1,
},
() => Action1(),
() => Action2()
);
}
上面的代码设置成了1,其实就是串行执行了。
执行时间如下。
4.2 CancellationSourceToken
同样可以通过ParallelOption指定CancellationSourceToken,多个并行任务之间可以协调取消
class ParallelInvoke
{
public void Action1(CancellationTokenSource cts)
{
cts.Cancel();
Thread.Sleep(3000);
Console.WriteLine("in action1");
}
public void Action2(CancellationTokenSource cts)
{
if (cts.IsCancellationRequested)
{
return;
}
Thread.Sleep(3000);
Console.WriteLine("in action2");
}
public void ParallelAction()
{
CancellationTokenSource cts = new CancellationTokenSource();
Parallel.Invoke
(
new ParallelOptions()
{
CancellationToken = cts.Token,
},
() => Action1(cts),
() => Action2(cts)
);
}