并行 LINQ (PLINQ) 是 LINQ to Objects 的并行实现。 PLINQ 实现完整的 LINQ 标准查询运算符集作为 T:System.Linq 命名空间的扩展方法,并具有用于并行运算的其他运算符。 PLINQ 将 LINQ 语法的简洁和可靠性与并行编程的强大功能结合在一起。 就像面向任务并行库的代码一样,PLINQ 查询会根据主计算机的能力按比例调整并发程度。

在许多情况下,PLINQ 可通过更有效地使用主计算机上的所有可用内核来显著提高 LINQ to Objects 查询的速度。 这一性能提升将使桌面具备高性能计算能力。

为了实现加速,PLINQ 查询必须具有足够的适合并行工作来弥补开销。 工作可表示为每个委托的计算开销与源集合中元素数量的乘积。 假定某个操作可并行化,则它的计算开销越高,加速的可能性就越大。 例如,如果某个函数执行花费的时间为 1 毫秒,则针对 1000 个元素进行的顺序查询将花费 1 秒来执行该操作,而在四核计算机上进行的并行查询可能只花费 250 毫秒。 这样就产生了 750 毫秒的加速。 如果该函数对于每个元素需要花费 1 秒来执行,则加速将为 750 秒。 如果委托的开销很大,则对于源集合中的很少几个项,PLINQ 可能会提供明显的加速。 相反,包含无关紧要委托的小型源集合通常不适合于 PLINQ。 ——MSDN

1.普通示例

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
 
namespace PLinq
{
    class Program
    {
        static IList<Person> _persons = new List<Person>();
        static void Main(string[] args)
        {
            try
            {
                CreateTextDB();
                PLINQ_Where();
            }
            catch (Exception ex)
            {
                Console.WriteLine(string.Format("Exception Message:{0}", ex.Message.Trim()));
            }
            finally
            {
                Console.ReadLine();
            }
        }
        /// <summary>
        /// 筛选
        /// </summary>
        private static void PLINQ_Where()
        {
            Stopwatch _wacth = new Stopwatch();
            _wacth.Start();
            IList<Person> _personWhereNormal = _persons.Where(p => p.Age > 10 && p.Age < 50).ToList();
            _wacth.Stop();
            Console.WriteLine(string.Format("Normal LINQ Where Cost Time:{0}", _wacth.ElapsedMilliseconds));
            _wacth.Restart();
            //WithDegreeOfParallelism
            IList<Person> _personWhereParallel = _persons.AsParallel<Person>().Where(p => p.Age > 10 && p.Age < 50).ToList();
            _wacth.Stop();
            Console.WriteLine(string.Format("PLINQ Where Cost Time:{0}", _wacth.ElapsedMilliseconds));
        }
        /// <summary>
        /// 创建测试数据
        /// </summary>
        private static void CreateTextDB()
        {
            Stopwatch _wacth = new Stopwatch();
            _wacth.Start();
            Parallel.For(0, 10000000, (i, loopstatus) =>
            {
                Person _person = new Person();
                _person.FristName = "Yan";
                _person.LastName = string.Format("Zhiwei {0}", i);
                _person.RegisterTime = DateTime.Now;
                _person.Age = i;
                lock (((ICollection)_persons).SyncRoot)
                {
                    _persons.Add(_person);
                }
            });
            _wacth.Stop();
            Console.WriteLine(string.Format("Create TextDB Cost Time:{0},Count:{1}", _wacth.ElapsedMilliseconds, _persons.Count));
        }
    }
    class Person
    {
        public string FristName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
        public DateTime RegisterTime { get; set; }
    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }代码效果

 

2.异常处理

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

namespace PLinq
{
    class Program
    {
        static IList<Person> _persons = new List<Person>();
        static void Main(string[] args)
        {
            try
            {
                CreateTextDB();
                PINQ_Exception();
            }
            catch (Exception ex)
            {
                Console.WriteLine(string.Format("Exception Message:{0}", ex.Message.Trim()));
            }
            finally
            {
                Console.ReadLine();
            }
        }
        private static void PINQ_Exception()
        {
            /*
             * 这样处理,当出现异常的时候不会影响下次foralll遍历
             */
            Func<int, bool> isTure = (age) =>
            {
                try
                {
                    if (age > 1989222)
                        throw new Exception("PLINQ Text");
                    Console.WriteLine(age);
                    return true;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    return false;
                }
            };
            _persons.AsParallel<Person>().ForAll(p => isTure(p.Age));

        }
        /// <summary>
        /// 创建测试数据
        /// </summary>
        private static void CreateTextDB()
        {
            Stopwatch _wacth = new Stopwatch();
            _wacth.Start();
            Parallel.For(0, 10000000, (i, loopstatus) =>
            {
                Person _person = new Person();
                _person.FristName = "Yan";
                _person.LastName = string.Format("Zhiwei {0}", i);
                _person.RegisterTime = DateTime.Now;
                _person.Age = i;
                lock (((ICollection)_persons).SyncRoot)
                {
                    _persons.Add(_person);
                }
            });
            _wacth.Stop();
            Console.WriteLine(string.Format("Create TextDB Cost Time:{0},Count:{1}", _wacth.ElapsedMilliseconds, _persons.Count));
        }
    }
    class Person
    {
        public string FristName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
        public DateTime RegisterTime { get; set; }
    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

代码效果

 

3.取消 PLINQ 查询

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace PLinq
{
    class Program
    {
        static IList<Person> _persons = new List<Person>();
        static void Main(string[] args)
        {
            try
            {
                CreateTextDB();
                PINQ_Cancellation();
            }
            catch (Exception ex)
            {
                Console.WriteLine(string.Format("Exception Message:{0}", ex.Message.Trim()));
            }
            finally
            {
                Console.ReadLine();
            }
        }
        private static void PINQ_Cancellation()
        {
            try
            {
                /*
                 * 当您在用户代码中处理取消时,不必在查询定义中使用 WithCancellation<TSource>。 但是,我们建议您这样做,原因是 WithCancellation<TSource> 对查询性能没有影响,
                 * 并且它使取消能够由查询运算符和用户代码进行处理。 为了确保系统响应能力,我们建议您大约每毫秒检查是否存在取消一次;
                 * 不过,任何 10 毫秒以下的期间都被视为可接受。 此频率对代码的性能应没有负面影响。 ——MSDN
                 */
                CancellationTokenSource _cancel = new CancellationTokenSource();
                Func<int, bool> isTure = (age) =>
                {
                    if (age > 1989222)
                        _cancel.Cancel();
                    Console.WriteLine(age);
                    return true;
                };
                _persons.AsParallel<Person>().WithCancellation(_cancel.Token).ForAll(p => isTure(p.Age));
            }
            catch (OperationCanceledException ex)
            {
                Console.WriteLine(string.Format("OperationCanceledException Message:{0}", ex.Message));
            }
        }
        /// <summary>
        /// 创建测试数据
        /// </summary>
        private static void CreateTextDB()
        {
            Stopwatch _wacth = new Stopwatch();
            _wacth.Start();
            Parallel.For(0, 10000000, (i, loopstatus) =>
            {
                Person _person = new Person();
                _person.FristName = "Yan";
                _person.LastName = string.Format("Zhiwei {0}", i);
                _person.RegisterTime = DateTime.Now;
                _person.Age = i;
                lock (((ICollection)_persons).SyncRoot)
                {
                    _persons.Add(_person);
                }
            });
            _wacth.Stop();
            Console.WriteLine(string.Format("Create TextDB Cost Time:{0},Count:{1}", _wacth.ElapsedMilliseconds, _persons.Count));
        }
    }
    class Person
    {
        public string FristName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
        public DateTime RegisterTime { get; set; }
    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

代码效果

[C#]『PLINQ』任务并行库使用小计的更多相关文章

  1. [C#]『CountdownEvent』任务并行库使用小计

    System.Threading.CountdownEvent  是一个同步基元,它在收到一定次数的信号之后,将会解除对其等待线程的锁定. CountdownEvent  专门用于以下情况:您必须使用 ...

  2. [C#]『Barrier』任务并行库使用小计

    Barrier  是一个对象,它可以在并行操作中的所有任务都达到相应的关卡之前,阻止各个任务继续执行. 如果并行操作是分阶段执行的,并且每一阶段要求各任务之间进行同步,则可以使用该对象. --MSDN ...

  3. [C#]『Task』任务并行库使用小计

    1.简单创建使用 using System; using System.Diagnostics; using System.Threading; using System.Threading.Task ...

  4. C# 任务并行库使用小计 z

    1.简单创建使用 using System; using System.Diagnostics; using System.Threading; using System.Threading.Task ...

  5. 『计算机视觉』imgaug图像增强库中部分API简介

    https://github.com/aleju/imgaug 介绍一下官方demo中用到的几个变换,工程README.md已经给出了API简介,个人觉得不好理解,特此单独记录一下: import n ...

  6. C#5.0之后推荐使用TPL(Task Parallel Libray 任务并行库) 和PLINQ(Parallel LINQ, 并行Linq). 其次是TAP(Task-based Asynchronous Pattern, 基于任务的异步模式)

    学习书籍: <C#本质论> 1--C#5.0之后推荐使用TPL(Task Parallel Libray 任务并行库) 和PLINQ(Parallel LINQ, 并行Linq). 其次是 ...

  7. 『TensorFlow』分布式训练_其二_单机多GPU并行&GPU模式设定

    建议比对『MXNet』第七弹_多GPU并行程序设计 一.tensorflow GPU设置 GPU指定占用 gpu_options = tf.GPUOptions(per_process_gpu_mem ...

  8. 『开源』Slithice 2013 服务器集群 设计和源码

    相关介绍文章: <『设计』Slithice 分布式架构设计-支持一体式开发,分布式发布> <『集群』001 Slithice 服务器集群 概述> <『集群』002 Sli ...

  9. 『计算机视觉』Mask-RCNN_推断网络其四:FPN和ROIAlign的耦合

    一.模块概述 上节的最后,我们进行了如下操作获取了有限的proposal, # [IMAGES_PER_GPU, num_rois, (y1, x1, y2, x2)] # IMAGES_PER_GP ...

随机推荐

  1. Harris角点算法

    特征点检测广泛应用到目标匹配.目标跟踪.三维重建等应用中,在进行目标建模时会对图像进行目标特征的提取,常用的有颜色.角点.特征点.轮廓.纹理等特征.现在开始讲解常用的特征点检测,其中Harris角点检 ...

  2. 对XML和YAML文件实现I/O操作

    1.文件的打开关闭 XML\YAML文件在OpenCV中的数据结构为FileStorage,打开操作例如: string filename = "I.xml"; FileStora ...

  3. Delphi- DLL操作

    动态链接库(Dynamic Link Library)是一个可以执行的并可以被多个Windows应用程序共享的程序模块(Module).模块中包含代码.数据和资源. 动态链接库的优点:不用重复编译和链 ...

  4. java10 WeakHashMap

    WeakHashMap: 对象所占用的区域是不能直接操作的,都是通过引用来操作. 引用分类: .强引用(StrongReference):gc(垃圾回收机制)运行时不回收.例如字符串常量池.字符串虽然 ...

  5. cocos js响应过程

    使用ccbi: js加载ccbi时候,会调用CCBReader的函数readNodeGraphFromData,从根节点递归解析子节点,使用readNodeGraph函数解析单个节点. 当碰到CCMe ...

  6. 触摸与手势学习-swift

    触摸是一个UITouch对象,该对象放在一个UIEvent中,每个UIEvent包含一个或多个UITouch对象,每个UITouch对象对应一个手指.系统将UIEvent发送到应用程序上,最后应用程序 ...

  7. 做一款仿映客的直播App?看我就够了

    来源:JIAAIR 链接:http://www.jianshu.com/p/5b1341e97757 一.直播现状简介   1.技术实现层面: 技术相对都比较成熟,设备也都支持硬编码.IOS还提供现成 ...

  8. Android(java)学习笔记155:如何让你的GridView不再滚动

    GridView显示不完整的原因是因为,他的外层也套用了一个滑动的控件,这个解决办法是:重写GridView,是控制GridView不能滚动,就是写一个类继承GridView   代码如下: publ ...

  9. 安卓开发中使用Genymotion模拟器

    在安卓开发中,运行和调试自己所写的安卓程序需要用到模拟器 在一般情况下 是直接在这创建一个模拟器,但是这种自带的模拟器运行效率不佳,而且启动时间漫长 所以,我们可以换一款安卓模拟器 Genymotio ...

  10. TCP三次握手/四次握手

    TCP连接三次握手 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资源.Client端接收到ACK报文后也向Server段发生ACK报文,并分配资源,这样 ...