[平行處理 - 1] Parallel.ForEach

  • 4853
  • 0
  • C#
  • 2018-04-09

假設媽媽跟你說 今天晚上九點時 你有三件事要做

1. 掃地 2. 洗澡 3. 洗碗

因為這三件事並不存在先後關係 所以哪件先做都可以

而聰明如你一定會想 如果我可以同時掃地、洗澡、洗碗一起做

那不是就太好了嗎

 

再次考量上面的例子

1. 每件事要花10分鐘、一次只做一件事總共要花30分鐘、但如果能三件事一起做則只要10分鐘

(假設你真的忙的過來)

2. 三件事之間並沒有先後關係,誰先誰後都沒差 

ex: 一定要先做 (煮飯+煮菜) => 才能吃飯,表示存在先後關係

 

執行結果會像這樣

可發現

1. 單執行序不管跑幾次 順序都是一樣的

2. 平行處理則無法控制先後順序

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

namespace ConsoleApplication1
{
    /// <summary>
    /// 示範 Parallel.ForEach
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            List<int> list = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            for (int i = 1; i <= 5; i++)
            {
                Console.WriteLine("【第" + i.ToString() + "回合】");
                Single(list);
                Multi(list);
                Console.WriteLine();
            }

            Console.Read();
        }

        private static void Single(List<int> list)
        {
            Console.Write("單執行緒");
            list.ForEach(i => Console.Write(i + ", "));
            Console.WriteLine();
            Console.WriteLine("-完成-");
        }

        private static void Multi(List<int> list)
        {
            Console.Write("平行處理");
            Parallel.ForEach(list, q =>
            {
                Console.Write(q + ", ");
            });
            Console.WriteLine();
            Console.WriteLine("-完成-");
        }
    }
}

 

最後跟大家分享一下我把他用在什麼地方

 

假設每個整點有三件事要做

1.備份100個很大的檔案、2.從資料庫撈出100萬筆資料寫成報表、3. 清cache 

 

可以猜測 1 跟 2 都涉及到一些 IO 與網路頻寬 所以可能會有效能瓶頸

3 則感覺應該不會慢到哪裡去

 

但若依序執行 將導致 3 明明是一個可以很快完成的任務 卻得被排在 1 跟 2 後面 等很久

此時便是 Parallel 能派上用場的時刻了