zoukankan      html  css  js  c++  java
  • C# Parallel之for,foreach使用(笔记)

      C# 4.0 的新特性之并行库(TPL), 是 .NET Framework 4的 System.ThreadingSystem.Threading.Tasks 命名空间中的一组公共类型和 API,基本包含以下几点:

      1. Parallel.For - for 循环的并行运算 
      2. Parallel.ForEach - foreach 循环的并行运算 
      3. Parallel.Invoke - 并行调用多个任务 
      4. Task - 任务,基于线程池。其使我们对并行编程变得更简单,且不用关心底层是怎么实现的
      5. PLINQ - 用于对内存中的数据做并行运算,也就是说其只支持 LINQ to Object 的并行运算

      今天先记录以下For,ForEach的基本使用,也是最常用到的。方便自己使用。

      1.如果遍历集合里面的元素,做没有关系的处理时:

        For:

    public static class ParallelFor_narmal
        {
            // 每个之间独立,不需要交互
            public static void narmal()
            {
                int[] arry = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    
                Parallel.For(0,arry.Length,(i,loopstate)=>
                {
                    Console.Out.WriteLine(arry[i]);
                });
            }
        }

        ForEach的情况差不多,这种情况是最简单的。其实也就可以使用泛型集合的ForEach(Action(T))方法了.

      2.如果集合里面的元素处理是有关联的,比如求和,但是并发是多线程的,按照传统的集合遍历肯定是有问题的,这个时候就需要了局部变量了。

        For: 

     public static long withlocalvariable() 
            {
    
               // int[] nums = Enumerable.Range(0, 1000000).ToArray();
                int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 };
                long total = 0;
                object lockflg = new object();
    
                // Use type parameter to make subtotal a long, not an int
                // 带有局部变量的并发。
                // 第一个参数是for循环的起始迭代位置
                // 第二个参数是for循环的终了迭代位置
                // 第三个参数是局部变量的初始化。Func(T)。 这里就是给每个线程局部变量subtotal初始化为0;
                // 第四个参数就是每个线程的执行的方法体。原型为Func(int,ParallelLoopState,T,B),具有三个入力参数和一个返回值的代理。
                //                其中j是运行时自动提供的迭代值,loop是用来控制循环的中断,subtotal就是局部变量,最有有一个返回值。
                // 第五个参数为具有一个入力参数,没有返回值的代理Action(T),用来处理每个线程的返回的结果。因为是多线程处理,所有要注意线程安全
                Parallel.For<long>(0, nums.Length, () => 0, (j, loop, subtotal) =>
                {
                    subtotal += nums[j];
                    return subtotal;
                },
                    (x) => 
                    { //Interlocked.Add(ref total, x);
                        lock (lockflg)
                        {
                            total += x; 
                        }
                    
                    }
                );
    
                return total;
            }

        ForEach:

    public static class ParallelForEach_WithLocalVariable
        {
            public static long withlocalvariable()
            {
                int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 };
                long total = 0;
                object lockflg = new object();
    
                //  ForEach<int, long> 第一个参数指定源元素的类型,此处的j,第二个参数指定线程本地变量的类型,此处的subtotal
                Parallel.ForEach<int, long>(nums,  // 数据源
                                           () => 0, // subtotal初始化
                                           (j, loop, subtotal) =>{ subtotal +=j;return subtotal;}, // 每个线程执行的方法体
                                           (x) =>{lock (lockflg) { total += x; }});  // 处理每个结果
    
                return total;
            }
        }

          这两种情况是最长使用到了,其实还有更细致的控制操作,有兴趣的可以看看 数据并行(任务并行库)

  • 相关阅读:
    Atitit 编程语言编程方法的进化演进 sp  COP ,AOP ,SOP
    Atitit 2016年attilax事业成就表
    Atitit 知识管理的重要方法 数据来源,聚合,分类,备份,发布 搜索
    Atitit webservice发现机制 WS-Discovery标准的规范attilax总结
    Atitit 多元化战略 适合我们发展 的核心业务attilax总结
    Atitit HTTP 认证机制基本验证 (Basic Authentication) 和摘要验证 (Digest Authentication)attilax总结
    Atitit. 提升存储过程与编程语言的可读性解决方案v3 qc25.docx
    Atitit zxing二维码qr码识别解析
    Atitit Data Matrix dm码的原理与特点
    Atitit 常用二维码对比(QR、PDF417、DM、汉信码 Aztec code maxicode
  • 原文地址:https://www.cnblogs.com/tangchd/p/3480246.html
Copyright © 2011-2022 走看看