C# 任务并行库

256 阅读2分钟

Task

功能

优劣

  • 优:Task类能对任务数量进行完全的控制
  • 劣:需要修改应用程序适用Task对象的引入;需要控制对操作进行同步;任务都完成后才能进行下一步;

Tips

  1. Task要求提供一个无返回值的委托
  2. 可以用'Task.ContinueWith'来实现任务延续(当上一个task干完之后干什么)
  3. 适用同一个Factory对象使任务保持一致性,适用Wait来实现任务同步

Code

Task task = new Task( doSomething);
Task newTask = task.ContinueWith(doMoreThing);//要求方法需要获取一个task参数,返回是对一个新task的引用
task.Start();

Task first = Task.Factory.StartNew(()=>...);
Task second = Task.Factory.StartNew(()=>...);
Task third = Task.Factory.StartNew(()=>...);
Task.WaitAll(first, second, third);

private doSomething()
{
    ...
}

private doMoreThing(Task task)
{
    ...
}

Parallel

功能

  • Parallel.Invoke 并行执行一组 Action 委托
  • Parallel.ForC#for循环的并行版本
  • Parallel.ForEach C#foreach循环的并行版本

优劣

  • 优:自动并行化;
  • 劣:循环体迭代的顺序不可知,要保证“计算限制独立” ;invoke方法需要独立且不依赖执行顺序;需要注意线程安全;

Tips

  1. Parallel.ForParallel.ForEach通常更适合用于外循环,而不是内循环。这是因为前者会带来更大的分区块,就稀释了管理并行的开销。一般没有必要同时并行内外循环;

  2. 对于并行的ForForEach循环,循环体是一个委托,所以就无法使用break语句来提前退出循环,使用ParallelLoopState对象上的BreakStop,调用Break会给出与顺序循环至少相同数量的元素,调用Stop会强制所有线程在当前迭代完成后立即结束;

Code

  1. Parallel.For(intStart,intEnd,Action(int i))
for (int i = 0; i < 100; i++)
  Foo (i);

并行版本是这样:

Parallel.For (0, 100, i => Foo (i));
  1. Parallel.Foreach
foreach (char c in "Hello, world")
  Foo (c);

并行版本是这样:

Parallel.ForEach ("Hello, world", Foo);
  1. Parallel.Invoke(dosomething,...)无参无返方法
Parallel.Invoke ( 
    () => new WebClient().DownloadFile ("http://www.linqpad.net", "lp.html"), 
    () => new WebClient().DownloadFile ("http://www.jaoo.dk", "jaoo.html"));

参考资料