基本的に、私が次のことをしたい場合:
public class SomeClass
{
private static ConcurrentDictionary<..., ...> Cache { get; set; }
}
これにより、sをあちこちで使用することを回避できますlock
か?
基本的に、私が次のことをしたい場合:
public class SomeClass
{
private static ConcurrentDictionary<..., ...> Cache { get; set; }
}
これにより、sをあちこちで使用することを回避できますlock
か?
はい、それはスレッドセーフであり、はい、それはあなたがいたるところにロックを使用することを避けます(それが意味するものは何でも)。もちろん、これはこのディクショナリに格納されているデータへのスレッドセーフアクセスのみを提供しますが、データ自体がスレッドセーフでない場合は、もちろんアクセスを同期する必要があります。たとえば、このキャッシュにを保存したとしますList<T>
。これで、thread1はこのリストをフェッチし(並行ディクショナリがこれを保証するため、スレッドセーフな方法で)、このリストの列挙を開始します。まったく同時に、thread2はこれとまったく同じリストをキャッシュからフェッチし(並行ディクショナリがこれを保証するのでスレッドセーフな方法で)、リストに書き込みます(たとえば、値を追加します)。結論:thread1を同期していないと、問題が発生します。
キャッシュとして使用する限り、それはおそらく良い考えではありません。キャッシングについては、フレームワークにすでに組み込まれているものをお勧めします。たとえば、 MemoryCacheなどのクラス。これは、アセンブリに組み込まれているものがSystem.Runtime.Caching
キャッシュ用に明示的に構築されているためです=>メモリが不足し始めた場合のデータの自動有効期限、キャッシュ有効期限アイテムのコールバックなどを処理します。 memcached、AppFabric、...など、同時辞書では夢にも思わないすべてのものを使用して、キャッシュを複数のサーバーに分散します。
データベースでトランザクションが必要になるのと同じ方法で、ロックを使用する必要がある場合があります。「並行」部分は、ディクショナリが複数のスレッドにわたって正しく機能し続けることを意味します。
並行コレクションには、誰かが最初にアイテムを削除する可能性があることを確認するTryGetValueとTryRemoveが組み込まれています。きめ細かいレベルでのロックが組み込まれていますが、それでもこれらの状況で何をすべきかを考える必要があります。キャッシングの場合、それはしばしば問題ではありません-つまり、べき等の操作です。
re:キャッシング。キャッシュに何を保存しているか、それを使って何をしているかに依存すると思います。オブジェクトの使用に関連するキャストコストがあります。おそらくほとんどのWebベースのものには、上記で提案したようにMemCacheの方が適しています。