C# のスレッドセーフリスト

Muhammad Maisam Abbas 2024年2月16日
  1. C# の ConcurrentBag クラスのスレッドセーフリスト
  2. C# の ConcurrentQueue クラスを使用したスレッドセーフリスト
  3. C# の SynchronizedCollection クラスを使用したスレッドセーフリスト
C# のスレッドセーフリスト

このチュートリアルでは、C# でスレッドセーフリストを作成する方法を紹介します。

C# の ConcurrentBag クラスのスレッドセーフリスト

ConcurrentBag クラスは、C# でスレッドセーフな順序付けられていないデータのコレクションを作成するために使用されます。ConcurrentBag クラスは C# の List と非常によく似ており、C# のスレッドセーフリストとして使用できます。ConcurrentBag クラスを使用するには、プロジェクトに System.Collections.Concurrent 名前空間をインポートする必要があります。複数のスレッドが ConcurrentBag オブジェクトに同時にアクセスできますが、ConcurrentBag オブジェクト内のコンテンツは同期的にのみ変更できます。並行操作のために複数のスレッドで使用可能であり、偶発的なデータ損失から安全になります。次のコード例は、C# で ConcurrentBag クラスを使用してスレッドセーフリストを作成する方法を示しています。

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;

namespace thread_safe_list {
  class Program {
    static void Main(string[] args) {
      ConcurrentBag<int> numbers = new ConcurrentBag<int>();
      numbers.Add(0);
      numbers.Add(1);
      numbers.Add(2);
      numbers.Add(3);
      numbers.Add(4);
      numbers.Add(5);
      Console.WriteLine("ConcurrentBag");
      foreach (var number in numbers) {
        Console.WriteLine(number);
      }
      List<int> nums = new List<int>();
      nums.Add(0);
      nums.Add(1);
      nums.Add(2);
      nums.Add(3);
      nums.Add(4);
      nums.Add(5);
      Console.WriteLine("List");
      foreach (var number in nums) {
        Console.WriteLine(number);
      }
    }
  }
}

出力:

ConcurrentBag
5
4
3
2
1
0
List
0
1
2
3
4
5

上記のコードでは、C# の ConcurrentBag クラスでスレッドセーフリストを作成しました。新しい要素 Add() を追加する関数は、ConcurrentBagList の両方のデータ構造で同じです。唯一の違いは、リストが先入れ先出し法(FIFO)で機能するのに対し、ConcurrentBag は後入れ先出し法(LIFO)で機能することです。この問題は、以下のコード例で対処されています。

C# の ConcurrentQueue クラスを使用したスレッドセーフリスト

ConcurrentQueue クラスは、C# でスレッドセーフなキューデータ構造を作成するために使用されます。ConcurrentQueue は、C# のリストと同様に、先入れ先出しの原則に基づいて機能します。List オブジェクトの代わりに ConcurrentQueue オブジェクトを使用して、スレッドセーフなデータ構造を作成できます。次のサンプルコードを参照してください。

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;

namespace thread_safe_list {
  class Program {
    static void Main(string[] args) {
      Console.WriteLine("Concurrent Queue");
      ConcurrentQueue<int> numbers = new ConcurrentQueue<int>();
      numbers.Enqueue(0);
      numbers.Enqueue(1);
      numbers.Enqueue(2);
      numbers.Enqueue(3);
      numbers.Enqueue(4);
      numbers.Enqueue(5);
      foreach (var number in numbers) {
        Console.WriteLine(number);
      }
      Console.WriteLine("List");
      List<int> nums = new List<int>();
      nums.Add(0);
      nums.Add(1);
      nums.Add(2);
      nums.Add(3);
      nums.Add(4);
      nums.Add(5);
      foreach (var number in nums) {
        Console.WriteLine(number);
      }
    }
  }
}

出力:

Concurrent Queue
0
1
2
3
4
5
List
0
1
2
3
4
5

上記のコードでは、C# の ConcurrentQueue クラスを使用してスレッドセーフなリストデータ構造を作成しました。ListConcurrentQueue のデータ構造で使用できるメソッドには、かなりの違いがあります。たとえば、List データ構造に新しい要素を追加するメソッドは Add() です。対照的に、ConcurrentQueue データ構造に新しい要素を追加する方法は Enqueue() であり、これは C# の従来の Queue データ構造とまったく同じです。ConcurrentQueue データ構造のこの欠点は、次の例で対処されます。

C# の SynchronizedCollection クラスを使用したスレッドセーフリスト

SynchronizedCollection クラスは、C# で指定されたタイプのオブジェクトのスレッドセーフなコレクションを作成するために使用されます。SynchronizedCollection データ構造は、C# の List データ構造と非常によく似ています。どちらのデータ構造も、先入れ先出しの原則に基づいて機能します。SynchronizedCollectionList データ構造の両方に新しい要素を追加する関数は Add() です。次の例を参照してください。

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;

namespace thread_safe_list {
  class Program {
    static void Main(string[] args) {
      Console.WriteLine("Synchronized Collection");
      SynchronizedCollection<int> numbers = new SynchronizedCollection<int>();
      numbers.Add(0);
      numbers.Add(1);
      numbers.Add(2);
      numbers.Add(3);
      numbers.Add(4);
      numbers.Add(5);
      foreach (var number in numbers) {
        Console.WriteLine(number);
      }
      Console.WriteLine("List");
      List<int> nums = new List<int>();
      nums.Add(0);
      nums.Add(1);
      nums.Add(2);
      nums.Add(3);
      nums.Add(4);
      nums.Add(5);
      foreach (var number in nums) {
        Console.WriteLine(number);
      }
    }
  }
}

出力:

Synchronized Collection
0
1
2
3
4
5
List
0
1
2
3
4
5

上記のコードでは、C# の SynchronizedCollection クラスを使用してスレッドセーフリストを作成しました。これまでのところ、このアプローチは、同じ FIFO の原則に従い、同じメソッドを使用しているため、C# でリストデータ構造の機能を実装するための他の 2つのアプローチの中で最適です。

Muhammad Maisam Abbas avatar Muhammad Maisam Abbas avatar

Maisam is a highly skilled and motivated Data Scientist. He has over 4 years of experience with Python programming language. He loves solving complex problems and sharing his results on the internet.

LinkedIn

関連記事 - Csharp Thread

関連記事 - Csharp List