zoukankan      html  css  js  c++  java
  • 《C#并行编程高级教程》第2章 命令式编程 笔记

    Parallel.Invoke

    并行执行多个方法,只有在所有方法都执行后才会返回
    static void Main(string[] args)
    {
        Parallel.Invoke(
        () => ConvertEllipses(),
        () => ConvertRectangles(),
        () => ConvertLines(),
        () => ConvertText());
        System.Console.ReadLine();
    }
     
    static void ConvertEllipses()
    {
        System.Console.WriteLine("Ellipses converted.");
    }
     
     
    static void ConvertRectangles()
    {
        System.Console.WriteLine("Rectangles converted.");
    }
     
    static void ConvertLines()
    {
        System.Console.WriteLine("Lines converted.");
    }
     
    static void ConvertText()
    {
        System.Console.WriteLine("Text converted.");
    }
     
    先给两段基本代码,方便后面理解。
    将Byte[]转成16进制表示的字符串
    private static string ConvertToHexString(Byte[] byteArray)
    {
        // Convert the byte array to hexadecimal string
        var sb = new StringBuilder(byteArray.Length);
        for (int i = 0; i < byteArray.Length; i++)
        {
            sb.Append(byteArray[i].ToString("X2"));
        }
        return sb.ToString();
    }
    生成一些AES的Key,并计时
    AesManaged在System.Security.Cryptography
    Stopwatch和Debug在System.Diagnostics
     
    private const int NUM_MD5_HASHES = 100000;
    private static void GenerateAESKeys()
    {
        var sw = Stopwatch.StartNew();
        var aesM = new AesManaged();
        for (int i = 1; i <= NUM_AES_KEYS; i++)
        {
            aesM.GenerateKey();
            byte[] result = aesM.Key;
            string hexString = ConvertToHexString(result);
            // Console.WriteLine("AES KEY: {0} ", hexString);
        }
        Debug.WriteLine("AES: " + sw.Elapsed.ToString());
    }
     

    Parallel.For

    不支持浮点数和进步。无法保证迭代执行的顺序
    private static void ParallelGenerateAESKeys()
    {
        var sw = Stopwatch.StartNew();
        Parallel.For(1, NUM_AES_KEYS + 1, (int i) =>
        {
            var aesM = new AesManaged();
            byte[] result = aesM.Key;
            string hexString = ConvertToHexString(result);
            // Console.WriteLine(“AES KEY: {0} “, hexString);
        });
        Debug.WriteLine("AES: " + sw.Elapsed.ToString());
    }

    Parallel.ForEach

    利用一个范围整数作为一组数据,通过一个分区器,把数据分成一组数据块。每一块的数据都通过循环的方式处理,而这些循环都是并行的。
    private static void ParallelPartitionGenerateAESKeys()
    {
        var sw = Stopwatch.StartNew();
        Parallel.ForEach(Partitioner.Create(1, NUM_AES_KEYS + 1), range =>
        {
            var aesM = new AesManaged();
            Debug.WriteLine(
                "AES Range ({0}, {1}. TimeOfDay before inner loop starts: {2})",
                range.Item1, range.Item2,
                DateTime.Now.TimeOfDay);
            for (int i = range.Item1; i < range.Item2; i++)
            {
                aesM.GenerateKey();
                byte[] result = aesM.Key;
                string hexString = ConvertToHexString(result);
                // Console.WriteLine(“AES KEY: {0} “, hexString);
            }
        });
        Debug.WriteLine("AES: " + sw.Elapsed.ToString());
    }

    根据内核数目优化分区

    Parallel.ForEach(
        Partitioner.Create(1,NUM_AES_KEYS,((int)(NUM_AES_KEYS / Environment.ProcessorCount) + 1)),
        range =>
        {
            //...
        });

    使用IEnumerable数据源

    private const int NUM_MD5_HASHES = 100000;
    private static IEnumerable<int> GenerateMD5InputData()
    {
        return Enumerable.Range(1, NUM_MD5_HASHES);
    }
     
    private static void ParallelForEachGenerateMD5Hashes()
    {
        var sw = Stopwatch.StartNew();
        var inputData = GenerateMD5InputData();
        Parallel.ForEach(inputData, (int number) =>
        {
            var md5M = MD5.Create();
            byte[] data =
                Encoding.Unicode.GetBytes(
                    Environment.UserName + number.ToString());
            byte[] result = md5M.ComputeHash(data);
            string hexString = ConvertToHexString(result);
            // Console.WriteLine("MD5 HASH: {0}", hexString);
        });
        Debug.WriteLine("MD5: " + sw.Elapsed.ToString());
    }

    从并行循环中退出

    在参数中使用ParallelLoopState,就可以使用loopState.Break();或者loopState.Stop();进行退出。其中的差别在于,假设调用Break的时候正在处理迭代100,那么可以保证小于100的迭代都被执行,而Stop不保证这个。
    ParallelLoopResult作为返回值,可以知道是否是正常完成或者被Break的
    ParallelLoopResult loopResult = Parallel.ForEach(inputData,
    (int number, ParallelLoopState loopState) =>
    {
        //...
        loopState.Break();
        return;
        //...
    });

    捕获并行循环的异常

    try
    {
        loopResult = Parallel.ForEach(inputData,
        (int number, ParallelLoopState loopState) =>
        {
            //...
            throw new Exception();
            //..
        });
    }
    catch (AggregateException ex)
    {
        foreach (Exception innerEx in ex.InnerExceptions)
        {
            Debug.WriteLine(innerEx.ToString());
        }
    }

    ParaleelOption

    用于修改并行度。
    private static void ParallelGenerateAESKeysMaxDegree(int maxDegree)
    {
        var parallelOptions = new ParallelOptions();
        parallelOptions.MaxDegreeOfParallelism = maxDegree;
        var sw = Stopwatch.StartNew();
        Parallel.For(1, NUM_AES_KEYS + 1, parallelOptions, (int i) =>
        {
            var aesM = new AesManaged();
            byte[] result = aesM.Key;
            string hexString = ConvertToHexString(result);
            // Console.WriteLine(“AES KEY: {0} “, hexString);
        });
        Debug.WriteLine("AES: " + sw.Elapsed.ToString());
    }
     
     





  • 相关阅读:
    一文解读RESTful (转)
    一文解读Redis (转)
    一文解读JSON (转)
    一文解读单点登录 (转)
    一文解读雪碧图 (转)
    一文解读骨架屏 (转)
    一文解读MPA/SPA(转)
    一文解读HTTP2 (转)
    一文解读HTTP (转)
    HTML5中Video标签无法播放mp4的解决办法
  • 原文地址:https://www.cnblogs.com/atskyline/p/3234292.html
Copyright © 2011-2022 走看看