1

複数のスレッドからアクセスされる Hashtable.Synchronized() によって作成された Hashtable のようなものがあるとします。キーと値のペアは Hashtable の Guid と Object です。スレッドの 1 つは、特定の Guid キーが別のスレッドによってこのリストに追加されるまで、この Hashtable をポーリングする必要があります。

以下は私のコードです。

        public Hashtable syncHt = new Hashtable();
        public void Init()
        {
            Hashtable ht = new Hashtable();
            syncHt = Hashtable.Synchronized(ht);
        }

アプリケーションの初期化では、init(); を呼び出します。

そして、スレッドの 1 つで、 isExist を呼び出して、他のスレッドによって追加された特定の Guid を見つけます。

public bool isExist(Guid sId)
    {
        while (true)
        {
            if (syncHt.ContainsKey(sId))
            {
                return true;
            }
        }

}

このループを終わらせることができるかどうか疑問に思っていました。ポーリング中にハッシュテーブルが変更されたことをどのように知ることができますか?ありがとう

4

2 に答える 2

2

並行コレクション、特にConcurrentBag<T>

アップデート

IsExistについては、こちらがより良い解決策です

チェンジHashtableオンConcurrentDictionary<Guid, object>なのでロック不要

repositoryロックなしでアイテムを追加

ConcurrentDictionary<Guid, object> repository = new ConcurrentDictionary<Guid, object>();

既存のアイテムのリポジトリを確認する

    public bool IsExist(Guid id)
    {
        SpinWait.SpinUntil(() => repository.ContainsKey(id)); - you can add Timout
        return true;
    }

SpinWaitの詳細はこちら

于 2012-08-05T16:18:06.107 に答える
1

.NET では、読み取りと参照へのより重要な割り当ては常にアトミックです。

アトミック操作を行うには、System.Threading.Interlockedクラスを使用します。MSDNを参照


このループを終わらせることができるかどうか疑問に思っていました。

別の (許可されているライターは 1 つだけ) スレッドが必要な値を挿入すると、終了します。はい。

MSDN について: Hashtable は、複数のリーダー スレッドと 1 つの書き込みスレッドで使用できるスレッド セーフです。

しかし、あなたのソリューションは非常に非効率的です。ビジー ループは、無駄に多くの CPU 時間を消費する可能性があります。(ボックス化された) Guid を古いスタイルのコレクションに格納することも完璧ではありません。

于 2012-08-05T15:39:25.457 に答える