Parallel类是对线程的一个抽象。该类位于System.Threading.Tasks名称空间中,提供了数据和任务并行性。
  Paraller类定义了数据并行地For和ForEach的静态方法,以及任务并行的Invoke的静态方法。Parallel.For()和Parallel.ForEach()方法在每次迭代中调用相同的代码,Paraller.Invoke()允许调用不同的方法。

1.Parallel.For
  Parallel.For()方法类似C#语法的for循环语句,多次执行一个任务。但该方法并行运行迭代,迭代的顺序没有定义。
  Parallel.For()方法中,前两个参数定义了循环的开头和结束,第三个参数是一个Action委托。Parallel.For方法返回类型是ParallelLoopResult结构,它提供了循环是否结束的信息。
  Parallel.For有多个重载版本和多个泛型重载版本。
  示例:

     static void ForTest()
{
ParallelLoopResult plr =
Parallel.For(,,i => {
Console.WriteLine("{0},task:{1},thread:{2}",i,Task.CurrentId,Thread.CurrentThread.ManagedThreadId);
Thread.Sleep();
}); if (plr.IsCompleted)
Console.WriteLine("completed!"); }

  输出:
  

  任务不一定映射到一个线程上。线程也可以被不同的任务重用。

  上面的例子,使用了.NET 4.5中新增的Thread.Sleep方法,而不是Task.Delay方法。Task.Delay是一个异步(http://www.cnblogs.com/afei-24/p/6757361.html)方法,用于释放线程供其它任务使用。
  示例:

  static void ForTestDelay()
{
ParallelLoopResult plr =
Parallel.For(, ,async i => {
Console.WriteLine("{0},task:{1},thread:{2}", i, Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
await Task.Delay();
Console.WriteLine("{0},task:{1},thread:{2}", i, Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
}); if (plr.IsCompleted)
Console.WriteLine("completed!"); Console.ReadKey(); }

  输出:
  
  上面代码使用了await关键字进行延迟,输出结果显示延迟前后的代码运行在不同的线程中。而且延迟后的任务不再存在,只留下线程,这里还重用了前面的线程。另一个重要的方面是,Parallel类的For方法并没有等待延迟,而是直接完成。parallel类只等待它创建的任务,而不等待其它后台活动。所以上面代码使用了Console.ReadKey();使主线程一直运行,不然很可能看不到后面的输出。

2.提前停止Parallel.For
  For()方法的一个重载版本接受第三个Action<int,ParallelLoopState>委托类型的参数。使用这个方法可以调用ParallelLoopState的Break()或Stop()方法,以停止循环。
  注意,前面说到,迭代的顺序是没有定义的。
  示例:

static void ForStop()
{
ParallelLoopResult plr =
Parallel.For(,,(int i,ParallelLoopState pls)=> {
Console.WriteLine("{0},task:{1},thread:{2}", i, Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
if (i > )
pls.Break();
}); Console.WriteLine("is completed:{0}",plr.IsCompleted);
Console.WriteLine("最低停止索引:{0}",plr.LowestBreakIteration);
}

  输出:
  
  迭代值在大于5时中断,但其它已开始的任务同时执行。

3.对Parallel.For中的每个线程初始化
  Parallel.For方法使用多个线程来执行循环,如果需要对每个线程进行初始化,就可以使用Parallel.For<TLocal>()方法。除了from和to对应的值之外,Parallel.For方法的泛型版本还接受3个委托参数:
    第一个委托参数的类型是Func<TLocal>,这个方法仅对用于执行迭代的每个线程调用每一次。
    第二个委托参数为循环体定义了委托。该参数类型是Func<int, ParallelLoopState, TLocal, TLocal>。其中第一个参数是循环迭代,第二个参数ParallelLoopState允许停止循环,第三个参数接受从上面参数委托  Func<TLocal>返回的值,该委托还需返回一个TLocal类型的值。该方法对每次迭代调用。
    第三个委托参数指定一个委托Action<TLocal>,接受第二个委托参数的返回值。这个方法仅对用于执行迭代的每个线程调用每一次。

  示例:

      static void ForInit()
{
ParallelLoopResult plr =
Parallel.For(,,()=> {
Console.WriteLine("init thread:{0},task:{1}",Thread.CurrentThread.ManagedThreadId,Task.CurrentId);
return Thread.CurrentThread.ManagedThreadId.ToString();
},
(i, pls,strInit)=> {
Console.WriteLine("body:{0},strInit:{1},thraed:{2},task:{3}",i,strInit,Thread.CurrentThread.ManagedThreadId,Task.CurrentId);
return i.ToString();
},
(strI)=> {
Console.WriteLine("finally {0}",strI);
});
}

  输出:
  

4.Parallel.ForEach
  Parallel.ForEach方法遍历实现了IEnumerable的集合,类似于foreach,但以异步方式遍历。没有确定遍历顺序。

  示例:

    static void ForeachTest()
{
string[] data = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve" };
ParallelLoopResult plr = Parallel.ForEach<string>(data, s =>
{
Console.WriteLine(s);
}); if (plr.IsCompleted)
Console.WriteLine("completed!");
}

  如果需要中断,可以使用ForEach的重载版本和参数ParallelLoopState。
  访问索引器:

    ParallelLoopResult plr1 = Parallel.ForEach<string>(data, (s,pls,l) =>
{
Console.WriteLine("data:{0},index:{1}",s,l);
});

5.Parallel.Invoke
  如果多个任务并行运行,可以使用Parallel.Invoke方法。该方法允许传递一个Action委托数组。

    static void ParallerInvoke()
{
Action[] funs = { Fun1,Fun2}; Parallel.Invoke(funs);
} static void Fun1()
{
Console.WriteLine("f1");
Console.WriteLine("task:{0},thread:{1}", Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
}
static void Fun2()
{
Console.WriteLine("f2");
Console.WriteLine("task:{0},thread:{1}", Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
}

多线程之Parallel类的更多相关文章

  1. Java基础-进程与线程之Thread类详解

    Java基础-进程与线程之Thread类详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.进程与线程的区别 简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程 ...

  2. 【C#】线程之Parallel

    在一些常见的编程情形中,使用任务也许能提升性能.为了简化变成,静态类System.Threading.Tasks.Parallel封装了这些常见的情形,它内部使用Task对象. Parallel.Fo ...

  3. 并行编程多线程之Parallel

    1.简介 随着多核时代的到来,并行开发越来越展示出它的强大威力!使用并行程序,充分的利用系统资源,提高程序的性能.在.net 4.0中,微软给我们提供了一个新的命名空间:System.Threadin ...

  4. 多线程之ThreadLocal类

    深入研究java.lang.ThreadLocal类 0.前言 ThreadLocal(线程变量副本)Synchronized实现内存共享,ThreadLocal为每个线程维护一个本地变量.采用空间换 ...

  5. C#多线程之Parallel中 类似于for的continue,break的方法

    好久没写东西了,终于找到点知识记录下... 利用ParallelLoopState对象来控制Parallel.For函数的执行,ParallelLoopState对象是由运行时在后台创建的: Para ...

  6. C# 多线程之Thread类

    使用System.Threading.Thread类可以创建和控制线程. 常用的构造函数有:   // 摘要: // 初始化 System.Threading.Thread 类的新实例,指定允许对象在 ...

  7. 多线程之Thread类

    Java并发编程:Thread类的使用 在前面2篇文章分别讲到了线程和进程的由来.以及如何在Java中怎么创建线程和进程.今天我们来学习一下Thread类,在学习Thread类之前,先介绍与线程相关知 ...

  8. 多线程之Tread类和Runnable的区别

    一.run()方法和start()方法的区别 在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类是在java.lang包中定义的.一个类只要继 ...

  9. JUC多线程之ThreadPoolExecutor类任务执行流程

    ThreadPoolExecutor类: ThreadPoolExecutor是我们最常用的一个线程池类,它实现了AbstractExecutorService接口.首先来看一下它的构造器及相关关键变 ...

随机推荐

  1. Android中java层使用LocalSocket和底层进行通讯

    原始文件:frameworks\base\services\java\com\android\server\NativeDaemonConnector.java private void listen ...

  2. Shiro基础学习(一)—权限管理

    一.基本概念 1.权限管理      只要有用户参与的系统一般都要有权限管理,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户可以访问而且只能访问自己被授权的资源.     权限管理 ...

  3. Sphinx安装流程及配合PHP使用经验

    1.什么是Sphinx Sphinx是俄罗斯人Andrew Aksyonoff开发的高性能全文搜索软件包,在GPL与商业协议双许可协议下发行. 全文检索式指以文档的全部文本信息作为检索对象的一种信息检 ...

  4. webx request注入单例增强实现

    由于在spring中request对象的scope限制导致了request对象无法直接注入到单例bean中,所以webx对其进行了增强实现,达到单例注入的目的. 实现原理大致如下: 1 启动时注册全局 ...

  5. 如何做到机器学习竞赛Kaggle排名前2%

    原创文章,同步首发自作者个人博客 .转载请务必在文章开头显眼处注明出处 摘要 本文详述了如何通过数据预览,探索式数据分析,缺失数据填补,删除关联特征以及派生新特征等方法,在Kaggle的Titanic ...

  6. 关于下拉框列表不可选择相同值的设置一:当前DOM不可选

    <!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8" ...

  7. 如何选择合适的PHP开发框架

    PHP作为一门成熟的WEB应用开发语言,已经深受广大开发者的青睐.与此同时,各式各样的PHP开发框架也从出不穷,面对如此多而且良莠不齐的开发框架,开发者们想必都会眼花缭乱,不知道该选择用哪个.其实并没 ...

  8. 【割点】【割边】tarjan

    洛谷割点模板题--传送门 割边:在连通图中,删除了连通图的某条边后,图不再连通.这样的边被称为割边,也叫做桥.割点:在连通图中,删除了连通图的某个点以及与这个点相连的边后,图不再连通.这样的点被称为割 ...

  9. Laravel框架一:原理机制篇

    Laravel作为在国内国外都颇为流行的PHP框架,风格优雅,其拥有自己的一些特点.以下是本人一点粗浅的认识,不敢奢求他人同意,更不能一一而足,仅为自己做一点总结而已. 一. 请求周期 Laravel ...

  10. Ubuntu14.04双网卡主备配置

    近日有个需求,交换机有两台,做了堆叠,服务器双网卡,每个分别连到一台交换机上.这样就需要将服务器的网卡做成主备模式,以增加安全性,使得当其中一个交换机不通的时候网卡能够自动切换. 整体配置不难,网上也 ...