#副標=平行運算程式開發 #大標=開創平行運算的新紀元 #作者=王寧疆 ========box 範例1======== 首先請在類別原始檔案最前面引入以下的名稱空間: using System.Threading.Tasks; using System.Collections.Concurrent; 然後於類別中建立以下的集合: BlockingCollection bc = new System.Collections.Concurrent.BlockingCollection< string>(); //建立BlockingCollection集合 再為類別加入以下的GetOdd和GetEven方法,分別負責判斷數字是否為奇數或偶數: void GetOdd() //判斷數字是否為奇數的方法 { for (int i = 0; i <= 1000; i++) //判斷0~1000之間的數字何者為奇數 { if (i % 2 != 0) //判斷i除以2的餘數是否不等於0 { bc.Add(string.Format("{0}是奇數",   //準備輸出的字串內容,並加入到BlockingCollection集合 } } } void GetEven() //判斷數字是否為偶數的方法 { for (int i = 0; i <= 1000; i++) //判斷0~1000之間的數字何者為偶數 { if (i % 2 == 0) //判斷i除以2的餘數是否等於0 { bc.Add(string.Format("{0}是偶數",i)); //準備輸出的字串內容,並加入到BlockingCollection集合 } } } ===========end========== ========box 範例2 ======== Parallel.Invoke(new Action(GetOdd), new Action(GetEven)); ===========end========== ========box 範例3 ======== for (int i=0; i < bc.Count;i++) //取出BlockingCollection集合的每一個元素 { listBox1.Items.Add(bc.ElementAt(i)); //將取得的元素內容加入到ListBox的Items集合中 } ===========end========== ========box 範例4======== using System.Threading.Tasks; using System.Collections.Concurrent; ===========end========== ========box 範例5 ======== BlockingCollection bc = new  System.Collections.Concurrent.BlockingCollection<  string>(); //建立BlockingCollection集合 ===========end========== ========box 範例6 ======== Parallel.For(1, 101, (i) => { var result = i*i; //對i執行平方運算 bc.Add(string.Format("{0}的平方={1}", i, result)); //將運算的結果放入BlockingCollection集合 } ); ===========end========== ========box 範例 7======== for (int i=0; i < bc.Count;i++) //取出BlockingCollection集合的每一個元素 { listBox2.Items.Add(bc.ElementAt(i)); //將取得的元素內容加入到ListBox的Items集合中 } ===========end========== ========box 範例8 ======== using System.Threading.Tasks; using System.Collections.Concurrent; ===========end========== ========box 範例9 ======== BlockingCollection bc = new System.Collections.Concurrent.BlockingCollection< string>(); //建立BlockingCollection集合 ===========end========== ========box 範例 10======== string ReturnOdd() //判斷數字是否為奇數的方法 { for (int i = 0; i <= 1000; i++) //判斷0~1000之間的數字何者為奇數 { if (i % 2 != 0) //判斷i除以2的餘數是否不等於0 { bc.Add(string.Format("{0}是奇數", i)); //準備輸出的字串內容,並加入到BlockingCollection集合 } } return "ReturnOdd Done!";  //傳回執行結束的字串 } string ReturnEven() //判斷數字是否為偶數的方法 { for (int i = 0; i <= 1000; i++) //判斷0~1000之間的數字何者為偶數 { if (i % 2 == 0) //判斷i除以2的餘數是否等於0 { bc.Add(string.Format("{0}是偶數", i)); //準備輸出的字串內容,並加入到BlockingCollection集合 } } return "ReturnEven Done!";  //傳回執行結束的字串 } ===========end========== ========box 範例11 ======== Task tOdd = new Task( ReturnOdd); //指定ReturnOdd方法是可以平行執行的工作 Task tEven = new Task( ReturnEven); //指定ReturnEven方法是可以平行執行的工作 tOdd.Start(); //以平行運算的方法執行ReturnOdd方法 tEven.Start(); //以平行運算的方法執行ReturnEven方法 listBox3.Items.Add(tOdd.Result); //將ReturnOdd方法執行之後的傳回值顯示到listBox3控制項 listBox3.Items.Add(tEven.Result); //將ReturnEven方法執行之後的傳回值顯示到listBox3控制項 ===========end========== ========box 範例12 ======== for (int i=0; i < bc.Count;i++) //取出BlockingCollection集合的每一個元素 { listBox3.Items.Add(bc.ElementAt(i));  //將取得的元素內容加入到ListBox的Items集合中 } ===========end========== ========box 範例13 ======== Task tOdd = new Task( ReturnOdd); //指定ReturnOdd方法是可以平行執行的工作 Task tEven = new Task( ReturnEven); //指定ReturnEven方法是可以平行執行的工作 tOdd.Start(); //以平行運算的方法執行ReturnOdd方法 tEven.Start(); //以平行運算的方法執行ReturnEven方法 ===========end========== ========box 範例14 ======== Task tOdd = Task.Factory.StartNew( () => ReturnOdd()); //指定ReturnOdd方法是可以平行執行的工作並立即執行之 Task tEven = Task.Factory.StartNew( () => ReturnEven()); //指定ReturnEven方法是可以平行執行的工作並立即執行之 ===========end========== ========box 範例 15======== using System.Threading; ===========end========== ========box 範例16 ======== CancellationTokenSource cTokenSource = null; ===========end========== ========box 範例 17======== void GetEvenWithCancel(CancellationToken ct) { for (int i = 0; i <= 1000; i++)   //判斷0~1000之間的數字何者為偶數 { Thread.Sleep(100); //延遲0.1秒 if (ct.IsCancellationRequested) //判斷平行運算的工作是否被取消? { break;     //如果被取消則結束判斷偶數的迴圈 } Else //平行運算的工作未被取消 { if (i % 2 == 0) //判斷i除以2的餘數是否等於0 { bc.Add(string.Format("{0}是偶數", i)); //準備輸出的字串內容,並加入到BlockingCollection集合 } } } } ===========end========== ========box 範例18 ======== cTokenSource = new CancellationTokenSource(); //建立CancellationTokenSource類別的物件 CancellationToken cToken = cTokenSource.Token; //利用CancellationTokenSource類別的物件取  //得CancellationToken類別的物件 Task t1 = Task.Factory.StartNew(() => GetEvenWithCancel(cToken), cToken); //將CancellationToken類別的物件傳遞給利用平行運算技術執行的方法 cToken.Register(() => cancelNotification()); //呼叫CancellationToken類別的物件的Register方法指定平行運 //算工作結束後必須呼叫的方法的名稱為cancelNotification ===========end========== ========box 範例 19======== void cancelNotification() { listBox4.Items.Add("平行運算工作被取消!");  //加入工作被取消的文字到ListBox控制項 } ===========end========== ========box 範例20 ======== listBox4.Items.Clear(); //清除ListBox控制項現有的內容 for (int i = 0; i < bc.Count; i++) //取出BlockingCollection集合的每一個元素 { listBox4.Items.Add(bc.ElementAt(i)); //將取得的元素內容加入到ListBox的Items集合中 } cTokenSource.Cancel(); //呼叫CancellationTokenSource類別的物件的 //Cancel方法取消平行運算的工作 ===========end========== ========box 範例21 ======== //呼叫Parallel類別的ForEach方法,逐一將放在fi集合中的圖檔名稱放入f變數以便進行縮圖處理 Parallel.ForEach(fi, f => { Bitmap bmp = new Bitmap(f.FullName);  //建立管理圖形檔案的Bitmap類別的物件 System.Drawing.Image ThumbnailImage =  bmp.GetThumbnailImage(160, 120, myCallback,   IntPtr.Zero);   //為圖檔建立160*120大小的縮圖 ThumbnailFileName = string.Format("{0}\\{1}{2}", NewPath, f.Name,   ".png"); //準備縮圖的檔案名稱 ThumbnailImage.Save(ThumbnailFileName, ImageFormat.Png);  //儲存動態產生的縮圖 ThumbnailImage.Dispose();  //丟棄ThumbnailImage物件 bmp.Dispose(); //丟棄bmp物件 } ===========end========== ========box 範例 22======== public bool ThumbnailCallback() { return false; } ===========end==========