国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

[C#]『Parallel.For』『Parallel.ForEach』任務并行庫使用小計

2019-11-14 16:47:54
字體:
來源:轉載
供稿:網友

Parallel 類提供對并行循環和區域的支持。

許多個人計算機和工作站都有兩個或四個內核(即 CPU),使多個線程能夠同時執行。 在不久的將來,計算機預期會有更多的內核。 為了利用當今和未來的硬件,您可以對代碼進行并行化,以將工作分攤在多個處理器上。 過去,并行化需要線程和鎖的低級操作。 Visual Studio 2010 和 .NET Framework 4 提供了新的運行時、新的類庫類型以及新的診斷工具,從而增強了對并行編程的支持。 這些功能簡化了并行開發,使您能夠通過固有方法編寫高效、細化且可伸縮的并行代碼,而不必直接處理線程或線程池。 下圖從較高層面上概述了 .NET Framework 4 中的并行編程體系結構。

IC387462

上面是MSDN對于并行任務的解釋,簡而言之就是同時執行多個任務,帶來效率上的提高,但是同時帶來CPU占用;

 

1.簡單Parallel.For/Parallel.ForEach循環

using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
 
namespace Consoleapplication17
{
    class PRogram
    {
        static void Main(string[] args)
        {
            try
            {
                NormalFor();
                ParallelFor();
            }
            catch (Exception ex)
            {
                Console.WriteLine(string.Format("Exception Message:{0}", ex.Message.Trim()));
            }
            finally
            {
                Console.ReadLine();
            }
        }
        static int _forCount = 100;
        static void NormalFor()
        {
            Stopwatch _watch = new Stopwatch();
            _watch.Start();
            for (int i = 0; i < _forCount; i++)
            {
                DoSomeWork(i);
            }
            _watch.Stop();
            Console.WriteLine(string.Format("Normal For Cost Time:{0}", _watch.ElapsedMilliseconds));
        }
        static void ParallelFor()
        {
            Stopwatch _watch = new Stopwatch();
            _watch.Start();
            //寫法一
            Parallel.For(0, _forCount, i =>
            {
                DoSomeWork(i);
            });
            _watch.Stop();
            Console.WriteLine(string.Format("Parallel For Cost Time:{0}", _watch.ElapsedMilliseconds));
            /*
            Parallel.For(0, _forCount, DoSomeWork);//寫法二
            Parallel.For(0, _forCount, (int i) => { DoSomeWork(i); });//寫法三
            */
        }
        static void DoSomeWork(int i)
        {
            if (i < 0)
                throw new ArgumentException("i");
            Thread.Sleep(100);
        }
    }
}

代碼效果

image

2.停止或中斷 Parallel.For 循環
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
 
namespace ConsoleApplication17
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                BreakParallelFor();
            }
            catch (Exception ex)
            {
                Console.WriteLine(string.Format("Exception Message:{0}", ex.Message.Trim()));
            }
            finally
            {
                Console.ReadLine();
            }
        }
        static int _forCount = 100;
        static void BreakParallelFor()
        {
            Parallel.For(0, _forCount, (i, status) =>
            {
                if (i == 22)
                {
                    Console.WriteLine("Parallel For Break....");
                    status.Break();
                }
                Console.WriteLine(string.Format("output :{0}", i));
                Thread.Sleep(100);
            });
        }
    }
}

代碼效果

image

看看MSDN關于此的解釋:

在 ParallelFor() 或 [Overload:System.Threading.Tasks.Parallel.Parallel.ForEach`1] 循環中,不能使用與順序循環中相同的 break 或 Exit 語句,這是因為這些語言構造對于循環是有效的,而并行“循環”實際上是方法,不是循環。 相反,可以使用 Stop 或 Break 方法。 Parallel.For的一些重載接受 Action<int, ParallelLoopState>(在 Visual Basic 中為 Action(Of Integer, ParallelLoopState))作為輸入參數。 ParallelLoopState 對象由運行時在后臺創建,您可以在 lambda 表達式中為它指定您喜歡的任何名稱。

在調用 Stop 或 Break 后,循環中的其他線程可能會繼續運行一段時間(這不受應用程序開發人員的控制),理解這一點很重要。 可以使用 ParallelLoopState.IsStopped 屬性檢查是否已在另一個線程上停止該循環。

理解黃色標注地方很重要;

 

3.具有線程局部變量的 Parallel.ForEach Parallel.For 循環

using System;using System.Linq;using System.Threading;using System.Threading.Tasks;namespace ConsoleApplication17{    class Program    {        static void Main(string[] args)        {            try            {                //例子參考自MSDN:http://msdn.microsoft.com/zh-cn/library/dd460703%28v=vs.100%29.aspx                int[] _nums = Enumerable.Range(0, 10).ToArray();                long _fortotal = 0, _foreahtotal = 0;                Parallel.For<long>(0, _nums.Length,                    () => 0,//每次遍歷開始時候初始化變量 類似于 int _subSum=0;                    (i, loopStatus, eachLoopTotal) =>//i:循環的索引;loopstatus:并行遍歷狀態;eachLoopTotal:每次遍歷累加小計值                    {                        eachLoopTotal += _nums[i];                        return eachLoopTotal;                    },                    (eachLoopTotal) =>//遍歷結束時候,將上面每次累加小計數值傳遞過來,進行總的累加                    {                        Interlocked.Add(ref _fortotal, eachLoopTotal);                    });                /*                localInit                    類型:System.Func<TLocal>                    用于返回每個線程的本地數據的初始狀態的函數委托。                body                    類型:System.Func<Int64, ParallelLoopState, TLocal, TLocal>                    將為每個迭代調用一次的委托。                localFinally                    類型:System.Action<TLocal>                    用于對每個線程的本地狀態執行一個最終操作的委托。                 */                Parallel.ForEach<int, long>(_nums,                      () => 0,                      (i, loopStatus, eachLoopTotal) =>                      {                          eachLoopTotal += _nums[i];                          return eachLoopTotal;                      },                      (eachLoopTotal) =>                      {                          Interlocked.Add(ref _foreahtotal, eachLoopTotal);                      });                Console.WriteLine("The Parallel.For is {0}", _fortotal);                Console.WriteLine("The Parallel.ForEach is {0}", _foreahtotal);            }            catch (Exception ex)            {                Console.WriteLine(string.Format("Exception Message:{0}", ex.Message.Trim()));            }            finally            {                Console.ReadLine();            }        }    }}
 
代碼效果

image

 

4.取消 Parallel.For/ForEach Loop

using System;
using System.Threading;
using System.Threading.Tasks;
 
namespace ConsoleApplication17
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                /*
                 CancellationToken 獲取或設置與此 ParallelOptions 實例關聯的 CancellationToken。 
                 MaxDegreeOfParallelism 獲取或設置此 ParallelOptions 實例所允許的最大并行度。 
                 TaskScheduler 獲取或設置與此 ParallelOptions 實例關聯的 TaskScheduler。 將此屬性設置為 null,以指示應使用當前計劃程序。
                 MaxDegreeOfParallelism MaxDegreeOfParallelism設置為2,表示最多可以有2個并行量(可以理解成并行線程數目),如果設置為為 -1,表示對于應該使用的并行量沒有上限設置。如果將其設置為1,則效果和單線程一樣.
                 */
                CancellationTokenSource _cancel = new CancellationTokenSource();
                ParallelOptions _po = new ParallelOptions();
                _po.CancellationToken = _cancel.Token;
                _po.MaxDegreeOfParallelism = Environment.ProcessorCount;
 
                Parallel.For(0, 100, _po, i =>
                    {
                        if (i == 22)
                            _cancel.Cancel();
                        Console.WriteLine(string.Format("output {0}", i));
                    });
            }
            catch (OperationCanceledException e)
            {
                Console.WriteLine(e.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine(string.Format("Exception Message:{0}", ex.Message.Trim()));
            }
            finally
            {
                Console.ReadLine();
            }
        }
    }
}

代碼效果

image


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 天门市| 垦利县| 大新县| 昌乐县| 施秉县| 英德市| 嵊州市| 石渠县| 南充市| 江达县| 巴林左旗| 商河县| 康平县| 普兰店市| 青浦区| 绥德县| 土默特左旗| 三都| 长治县| 宜君县| 诏安县| 甘泉县| 壶关县| 丽水市| 长顺县| 临汾市| 新化县| 洱源县| 客服| 葫芦岛市| 女性| 阳高县| 莎车县| 什邡市| 惠州市| 开封县| 合川市| 尼勒克县| 清苑县| 莱芜市| 连云港市|