C#
 Computer >> コンピューター >  >> プログラミング >> C#

C#入門:StringDictionaryへの同期アクセスを取得する方法(SyncRoot活用)

StringDictionaryは、キーと値がどちらも文字列型である特殊化されたハッシュテーブルコレクションです。マルチスレッド環境下でコレクションを安全に操作・列挙するには、SyncRootプロパティで取得できるオブジェクトに対してlockステートメントを適用し、同期アクセスを実現します。

以下に、実際のコード例を示します。

例1:SyncRootによる同期アクセス

using System;
using System.Collections;
using System.Collections.Specialized;
public class Demo {
    public static void Main(){
        StringDictionary strDict = new StringDictionary ();
        strDict.Add("A", "Books");
        strDict.Add("B", "Electronics");
        strDict.Add("C", "Appliances");
        strDict.Add("D", "Pet Supplies");
        strDict.Add("E", "Clothing");
        strDict.Add("F", "Footwear");
        Console.WriteLine("StringDictionary key-value pairs...");
        foreach(DictionaryEntry de in strDict) {
            Console.WriteLine(de.Key + " " + de.Value);
        }
        Console.WriteLine("Value associated with key D = "+strDict["D"]);
        Console.WriteLine("Value associated with key F = "+strDict["F"]);
        Console.WriteLine("\nSynchronize access..");
        lock(strDict.SyncRoot) {
            foreach(DictionaryEntry de in strDict) {
                Console.WriteLine(de.Key + " " + de.Value);
            }
        }
    }
}

出力結果

上記のコードを実行すると、次のような出力が得られます。

StringDictionary key-value pairs...
a Books
b Electronics
c Appliances
d Pet Supplies
e Clothing
f Footwear
Value associated with key D = Pet Supplies
Value associated with key F = Footwear
Synchronize access..
a Books
b Electronics
c Appliances
d Pet Supplies
e Clothing
f Footwear

出力結果から、lock(strDict.SyncRoot)ブロック内で列挙した場合も、通常の列挙とまったく同じキーと値のペアが表示されることが確認できます。また、StringDictionaryではキーが自動的に小文字に変換されて格納されるため、「A」〜「F」が「a」〜「f」として出力されている点にも注意してください。

ポイント解説

  • SyncRootプロパティ:コレクションへのアクセスを同期するために使用できるオブジェクトを返します。
  • lockステートメント:指定したオブジェクトに対して排他ロックを取得し、複数のスレッドが同時にコレクションへ読み書きすることを防ぎます。
  • 列挙中に他のスレッドからコレクションが変更されると例外が発生する可能性があるため、foreachによる列挙全体をlockブロックで囲むのが安全です。

例2:別のサンプルコード

続いて、もう一つの例を見てみましょう。

using System;
using System.Collections;
using System.Collections.Specialized;
public class Demo {
    public static void Main() {
        StringDictionary strDict = new StringDictionary();
        strDict.Add("A", "John");
        strDict.Add("B", "Andy");
        strDict.Add("C", "Tim");
        strDict.Add("D", "Ryan");
        strDict.Add("E", "Kevin");
        strDict.Add("F", "Katie");
        strDict.Add("G", "Brad");
        Console.WriteLine("StringDictionary elements...");
        foreach(DictionaryEntry de in strDict) {
            Console.WriteLine(de.Key + " " + de.Value);
        }
        Console.WriteLine("\nSynchronize access..");
        lock(strDict.SyncRoot) {
            foreach(DictionaryEntry de in strDict) {
                Console.WriteLine(de.Key + " " + de.Value);
            }
        }
    }
}

出力結果

このコードを実行すると、次の出力が得られます。

StringDictionary elements...
a John
b Andy
c Tim
d Ryan
e Kevin
f Katie
g Brad

Synchronize access..
a John
b Andy
c Tim
d Ryan
e Kevin
f Katie
g Brad

このように、SyncRootlockを組み合わせることで、StringDictionaryへの同期アクセスを簡単に実装できます。マルチスレッドアプリケーションで共有コレクションを扱う際には、この手法を活用してスレッドセーフな処理を実現しましょう。

  1. C#のStringDictionaryでキーのコレクションを取得する方法

    C#のStringDictionaryでキーのコレクションを取得する方法 StringDictionaryからキーのコレクションを取得するには、Keysプロパティを使用します。このプロパティは、ディクショナリに格納されているすべてのキーをICollectionオブジェクトとして返します。 さらに、CopyToメソッドを組み合わせれば、取得したキーのコレクションを文字列配列(String[])にコピーでき、インデックスを指定して個々のキーにアクセスすることも可能です。 以下では、実際のサンプルコードと実行結果をもとに、具体的な手順を解説します。 例1:Keysプロパティでキーの一覧を取得する u

  2. Windows 10/8のクイックアクセスメニュー(Win+Xメニュー)を自由にカスタマイズする方法

    クイックアクセスメニュー(パワーユーザーメニューとも呼ばれます)は、デバイスマネージャー、ディスクの管理、コマンドプロンプトといった高度なシステムツールへ最短でアクセスできる便利な機能です。この機能はWindows 8の登場とともに導入されました。 メニューを開くには、Windowsキー+Xキーを同時に押すか、スタートボタンを右クリックします。するとメニューがポップアップ表示されます。 しかし、初期状態の項目だけでは物足りなかったり、使わないプログラムを整理したいこともあるでしょう。そんなときは無料ツール「Win+X Menu Editor」を使えば、メニューを思い通りにカスタマイズできます。