外部アプリケーションからデータを取得します:
クラス DataItem { 公開文字列キー; public int Attribute1; 公開文字列 Attribute2; }
1 つのスレッドがコレクションに格納します。他のスレッド (3 ~ 10) は、キー (90%) および属性 (10%) によるコレクションのクエリを実行します。
コレクションに10、100、1000以上のアイテムがある場合、これを実装する最良の方法は何ですか?
外部アプリケーションからデータを取得します:
クラス DataItem { 公開文字列キー; public int Attribute1; 公開文字列 Attribute2; }
1 つのスレッドがコレクションに格納します。他のスレッド (3 ~ 10) は、キー (90%) および属性 (10%) によるコレクションのクエリを実行します。
コレクションに10、100、1000以上のアイテムがある場合、これを実装する最良の方法は何ですか?
コレクションが初期化後に不変(読み取り専用、変更されない)であり、スレッドがコレクションに到達する前にコレクションが初期化される場合、特別なことをする必要はありません。複数のスレッドは、問題なくコレクションまたはディクショナリから同時に読み取ることができます。
複数のスレッドによるアクションの結果として共有オブジェクト(コレクション)の状態が変化した場合にのみ、問題が発生します。複数のスレッドがコレクションから読み取っているときにコレクションを更新する場合、またはコレクションが内部キャッシュリストを維持している場合など、マルチスレッドアクセスで問題が発生する場合。
コレクションを静的コンストラクターで初期化された静的オブジェクトとして設定する場合は、初期化中にコレクションを保護するための明示的なロックも必要ありません。.NETは、最初に使用する前にクラスが初期化されることを保証します。
初期化後にコレクションが不変になるように問題を再定義できれば、多くの頭痛の種を避けて作業することができます。
インメモリ データベースが本当に必要な場合は、管理されたデータ プロバイダーを使用するSqliteが最適なオプションです。ただし、この場合、ConcurrencyDictionaryで問題ないと思います。このコレクションは、1000 以上のアイテムと、それに並行してアクセスする多くのスレッドを簡単に処理できます。このコレクションを使用する際の注意点は、コレクション内のエントリごとに 1 つのキーしか指定できないことです。検索する属性ごとに個別のコレクションを使用する必要がある場合があります。繰り返しますが、属性によるルックアップの頻度が十分に低い場合は、コレクション全体を列挙して、個別のコレクションを必要とせずに一致する属性を見つけることを選択できます。
インメモリコレクションは読み取り専用ですか?それはあなたが最終的に使用するものに違いをもたらします。
私の推奨事項-
読み取り専用:ConcurrentDictionaryを使用
読み取りと書き込み:DataSetを使用
私の意見では、最良の並行モデル、つまりスレッドセーフモデルはDataSetです。ADO.NetTackleDataConcurrencyおよびMSDNDataSetを参照してください。DataSetは、複数のクライアントのメモリ内データストレージを処理するために開発されました。MSDNの内容に注意してください。
このタイプは、マルチスレッド読み取り操作に対して安全です。書き込み操作を同期する必要があります。
Brian Gideonが示唆しているように、DataSetに代わるものがあります-ConcurrentDictionary。
DataReaderを使用すると、のようなカスタムオブジェクトをDataItem
DataReaderから直接入力できます。
いずれにせよ、これらのソリューションはどちらも、メモリ内のデータにすばやく同時にアクセスできるようにします。