0

キーと値のペアを静的な同期ディクショナリ(.NET 3.5、ConcurrentDictionaryではない)に格納すると同時に、それらにアクセスできる最も効率的な方法を探しています。

Dictionary.Add(key, value);

if (Dictionary.Count >= 200)
{
       foreach (KeyValuePair<string, Info> pair in Dictionary)
       {
              Info entry = pair.Value;
              StoreInDatabase(entry);
       }

       Dictionary.Clear();
}

ここに問題があります。別のユーザーがデータベースにアクセスして保存しているときに、あるユーザーが辞書に追加していると、辞書が壊れます。

lock (Dictionary)
{
    //Same Code Above
}

ロックを入れてみたらうまくいくようですが、もっと効率的な方法はないかと思います。思ったほど効率的ではありません。任意の提案をいただければ幸いです!

注:値を格納するには、StoreInDatabaseメソッドを使用する必要があります。


改訂されたコード:

private static SynchronizedDictionary<string, Info> Dictionary = new SynchronizedDictionary<string, Info>();

...

Dictionary.Add(key, value);

if (Dictionary.Count >= 200)
{
       SynchronizedDictionary<string, Info> temporaryDictionary = new SynchronizedDictionary<string, Info>();
       lock (Dictionary)
       {
            temporaryDictionary = Dictionary;
            Dictionary.Clear();
       }

       lock(temporaryDictionary)
       {
            foreach (KeyValuePair<string, Info> pair in temporaryDictionary)
            {
                  Info entry = pair.Value;
                  StoreInDatabase(entry);
            }
       }
}

これにより、パフォーマンスが大幅に向上しました。flqに感謝します!

4

2 に答える 2

3

DB操作をロックする必要があります。これは、メモリ内のアクティビティと比較して時間がかかります

ロック内で、DBに保存する値をコピーし、ディクショナリをクリアする必要があります。次に、辞書を解放すると、他のスレッドがDBに書き込みます。

また、デッドロックの可能性を最小限に抑えるために、プライベートロックオブジェクトを使用することも理にかなっています。

于 2012-05-30T13:59:26.700 に答える
1

利用可能な最も軽量な同期メカニズムであるInterlockedを使用して、スレッドセーフな辞書を実装しました。

ソースコードはここにあります。これは、リフレクションタスクをより簡単かつ高速にするのに役立つライブラリであるFasterflect用に作成されています。コードは#ifdefineを使用して、.NET 3.5のカスタムディクショナリを条件付きで有効にします。これは、ベンチマークで.NET4.0ConcurrentDictionaryがさらに高速であることを示しているためです。

flqが指摘しているように、ロックを保持したままデータベースにアクセスすることは非常に悪い考えです。真剣に、あなたがやりたいことではありません。保存する必要のあるデータを一時的なデータ構造にコピーするなど、より適切な解決策を見つけてください。

于 2012-05-30T14:39:06.433 に答える