欧美性猛交xxx嘿人猛交_又色又爽又高潮免费观看_精品国产一区二区三区久久影院_青娱乐极品视觉盛宴国产视频

技術頻道導航
HTML/CSS
.NET技術
IIS技術
PHP技術
Js/JQuery
Photoshop
Fireworks
服務器技術
操作系統(tǒng)
網站運營

贊助商

分類目錄

贊助商

最新文章

搜索

如何在C#中使用Parallel.For和Parallel.ForEach

作者:admin    時間:2023-6-5 17:29:11    瀏覽:

并行性是在具有多個內核的系統(tǒng)上并行執(zhí)行任務的能力。.NET Framework 4 中引入了對 .NET 中并行編程的支持。.NET 中的并行編程使我們能夠更有效地使用系統(tǒng)資源,并通過更好的編程控制。本文討論了我們如何在 .NET Core 應用程序中使用并行性。

要使用本文中提供的代碼示例,你應該在系統(tǒng)中安裝 Visual Studio 2019。

如何在C#中使用Parallel.For和Parallel.ForEach

在 Visual Studio 中創(chuàng)建 .NET Core 控制臺應用程序項目

首先,讓我們在 Visual Studio 中創(chuàng)建一個 .NET Core 控制臺應用程序項目。假設你的系統(tǒng)中安裝了 Visual Studio 2019,請按照下面概述的步驟在 Visual Studio 中創(chuàng)建一個新的 .NET Core 控制臺應用程序項目。

  1. 啟動 Visual Studio IDE。
  2. 單擊“創(chuàng)建新項目”。
  3. 在“創(chuàng)建新項目”窗口中,從顯示的模板列表中選擇“控制臺應用程序(.NET Core)”。
  4. 點擊下一步。
  5. 在“配置新項目”窗口中,指定新項目的名稱和位置。
  6. 單擊創(chuàng)建。

在本文的后續(xù)部分中,我們將使用該項目來說明 .NET Core 中的并行編程。

.NET Core 中的并發(fā)性和并行性

并發(fā)性和并行性是 .NET 和 .NET Core 中的兩個關鍵概念。盡管它們看起來相同,但它們之間存在細微差別。

考慮必須由應用程序執(zhí)行的兩個任務 T1 和 T2。如果一個任務處于執(zhí)行狀態(tài)而另一個任務等待輪到它,則這兩個任務處于并發(fā)執(zhí)行狀態(tài)。結果,其中一項任務先于另一項完成。相比之下,如果兩個任務同時執(zhí)行,則這兩個任務是并行執(zhí)行的。要實現(xiàn)任務并行,程序必須運行在多核 CPU 上。

.NET Core 中的 Parallel.For 和 Parallel.ForEach

Parallel.For 循環(huán)執(zhí)行可以并行運行的迭代。你可以監(jiān)視甚至操縱循環(huán)的狀態(tài)。Parallel.For 循環(huán)就像 for 循環(huán),只是它允許迭代在多個線程中并行運行。

Parallel.ForEach 方法將要完成的工作拆分為多個任務,每個任務對應集合中的每一項。Parallel.ForEach 類似于 C# 中的 foreach 循環(huán),除了 foreach 循環(huán)在單個線程上運行并且按順序進行處理,而 Parallel.ForEach 循環(huán)在多個線程上運行并且處理以并行方式進行。

C# 中的 Parallel.ForEach 與 foreach

考慮下面的方法,它接受一個整數(shù)作為參數(shù),如果它是質數(shù)則返回 true

static bool IsPrime(int integer)
{
    if (integer <= 1) return false;
    if (integer == 2) return true;
    var limit = Math.Ceiling(Math.Sqrt(integer));
    for (int i = 2; i <= limit; ++i)
        if (integer % i == 0)
            return false;
    return true;
}

我們現(xiàn)在將利用 ConcurrentDictionary 來存儲素數(shù)和托管線程 ID。由于兩個范圍之間的質數(shù)是唯一的,我們可以將它們用作鍵,將托管線程 ID 用作值。

.NET 中的并發(fā)集合包含在 System.Collections.Concurrent 命名空間內,并提供集合類的無鎖和線程安全實現(xiàn)。ConcurrentDictionary 類包含在 System.Collections.Concurrent 命名空間內,代表一個線程安全的字典。

以下兩個方法均使用 IsPrime 方法來檢查整數(shù)是否為素數(shù),將素數(shù)和托管線程 ID 存儲在 ConcurrentDictionary 的實例中,然后返回該實例。第一種方法使用并發(fā),第二種方法使用并行。

private static ConcurrentDictionary<int, int>
GetPrimeNumbersConcurrent(IList<int> numbers)
{
    var primes = new ConcurrentDictionary<int, int>();
    foreach (var number in numbers)
    {               
        if(IsPrime(number))
        {
            primes.TryAdd(number,
            Thread.CurrentThread.ManagedThreadId);
         }
     }
     return primes;
}
private static ConcurrentDictionary<int, int>
GetPrimeNumbersParallel(IList<int> numbers)
{
    var primes = new ConcurrentDictionary<int, int>();
    Parallel.ForEach(numbers, number =>
    {
        if (IsPrime(number))
        {
            primes.TryAdd(number,
            Thread.CurrentThread.ManagedThreadId);
        }
    });
    return primes;
}

C# 中的并發(fā)與并行示例

以下代碼片段說明了如何調用 GetPrimeNumbersConcurrent 方法來檢索 1 到 100 之間的所有質數(shù)以及托管線程 ID。

static void Main(string[] args)
{
    var numbers = Enumerable.Range(0, 100).ToList();
    var result = GetPrimeNumbersConcurrent(numbers);
    foreach(var number in result)
    {
        Console.WriteLine($"Prime Number:
        {string.Format("{0:0000}",number.Key)},
        Managed Thread Id: {number.Value}");
    }
    Console.Read();
}

當你執(zhí)行上面的程序時,你應該看到如圖 1 所示的輸出:

C#調用GetPrimeNumbersConcurrent方法來檢索1到100之間的所有質數(shù) 
圖1

如你所見,托管線程 ID 在每種情況下都是相同的,因為我們在此示例中使用了并發(fā)。現(xiàn)在讓我們看看使用線程并行時輸出會是什么樣子。以下代碼片段說明了如何使用并行性檢索 1 到 100 之間的素數(shù)。

static void Main(string[] args)
{
    var numbers = Enumerable.Range(0, 100).ToList();
    var result = GetPrimeNumbersParallel(numbers);
    foreach(var number in result)
    {
        Console.WriteLine($"Prime Number:
        {string.Format("{0:0000}",number.Key)},
        Managed Thread Id: {number.Value}");
    }
    Console.Read();
}

當你執(zhí)行上面的程序時,輸出應該類似于圖 2 所示: 

C#使用并行性檢索 1 到 100 之間的素數(shù) 
圖2

正如你在這里看到的,因為我們使用了 Parallel.ForEach,所以創(chuàng)建了多個線程,因此托管線程 ID 是不同的。

限制C#中的并行度

并行度是一個無符號整數(shù),表示你的查詢在執(zhí)行時應利用的最大處理器數(shù)。換句話說,并行度是一個整數(shù),表示將在同一時間點執(zhí)行以處理查詢的最大任務數(shù)。

默認情況下,Parallel.ForParallel.ForEach 方法對衍生任務的數(shù)量沒有限制。因此,在上面顯示的 GetPrimeNumbersParallel 方法中,程序嘗試使用系統(tǒng)中的所有可用線程。

你可以利用 MaxDegreeOfParallelism 屬性來限制衍生任務的數(shù)量(每個 Parallel 類的 ParallelOptions 實例)。如果 MaxDegreeOfParallelism 設置為 -1,則并發(fā)運行的任務數(shù)沒有限制。

以下代碼片段顯示了如何設置 MaxDegreeOfParallelism 以使用最多 75% 的系統(tǒng)資源。 

new ParallelOptions
{
    MaxDegreeOfParallelism = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 0.75) * 2.0))
};

請注意,在上面的代碼片段中,我們將處理器數(shù)量乘以二,因為每個處理器包含兩個內核。以下是 GetPrimeNumbersParallel 方法的完整更新代碼,供你參考:

private static ConcurrentDictionary<int, int> GetPrimeNumbersParallel(IList<int> numbers)
{
    var primes = new ConcurrentDictionary<int, int>();
    Parallel.ForEach(numbers, number =>
    {
        new ParallelOptions
        {
            MaxDegreeOfParallelism = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 0.75) * 2.0))
        };
        if (IsPrime(number))
        {
            primes.TryAdd(number,
            Thread.CurrentThread.ManagedThreadId);
        }
    });
    return primes;
}

確定 C# 中的并行循環(huán)是否完成

請注意,Parallel.ForParallel.ForEach 都返回一個 ParallelLoopResult 實例,該實例可用于確定并行循環(huán)是否已完成執(zhí)行。以下代碼片段顯示了如何使用 ParallelLoopResult

ParallelLoopResult parallelLoopResult = Parallel.ForEach(numbers, number =>
 {
    new ParallelOptions
    {
          MaxDegreeOfParallelism = Convert.ToInt32(Math.Ceiling(
          (Environment.ProcessorCount * 0.75) * 2.0))
    };
    if (IsPrime(number))
    {
          primes.TryAdd(number, Thread.CurrentThread.ManagedThreadId);
    }
 });
Console.WriteLine("IsCompleted: {0}", parallelLoopResult.IsCompleted);

要在非泛型集合中使用 Parallel.ForEach,你應該利用 Enumerable.Cast 擴展方法將集合轉換為泛型集合,如下面的代碼片段所示。

Parallel.ForEach(nonGenericCollection.Cast<object>(),
currentElement =>
{
});

最后一點,不要假設 Parallel.ForParallel.ForEach 的迭代將始終并行執(zhí)行。你還應該注意線程親和性問題。你可以閱讀有關任務并行性的潛在缺陷。

總結

本文討論了如何在C#中使用Parallel.ForParallel.ForEach的問題。通過本文的學習,你應該了解了C#中Parallel.ForParallel.ForEach的使用方法及注意問題。

相關文章

x