基本上,如果我想做以下事情:
public class SomeClass
{
private static ConcurrentDictionary<..., ...> Cache { get; set; }
}
这是否让我避免lock
在所有地方使用 s ?
基本上,如果我想做以下事情:
public class SomeClass
{
private static ConcurrentDictionary<..., ...> Cache { get; set; }
}
这是否让我避免lock
在所有地方使用 s ?
是的,它是线程安全的,是的,它可以避免你到处使用锁(不管这意味着什么)。当然,这只会为您提供对该字典中存储的数据的线程安全访问,但如果数据本身不是线程安全的,那么您当然需要同步访问它。例如,假设您在此缓存中存储了一个List<T>
. 现在 thread1 获取此列表(以线程安全的方式,因为并发字典向您保证这一点),然后开始枚举此列表。在同一时间,thread2 从缓存中获取这个相同的列表(以线程安全的方式,因为并发字典向您保证这一点)并写入列表(例如,它添加一个值)。结论:如果你没有同步thread1,它会遇到麻烦。
就将其用作缓存而言,这可能不是一个好主意。对于缓存,我会向您推荐框架中已经内置的内容。例如MemoryCache之类的类。这样做的原因是,System.Runtime.Caching
程序集中内置的内容是为缓存而明确构建的 => 如果您开始内存不足,它会处理数据自动过期,缓存过期项目的回调,您甚至可以使用诸如 memcached、AppFabric 之类的东西将您的缓存分布在多个服务器上,...,所有这些都是您使用并发字典无法想象的。
您可能仍然需要以与您可能需要数据库中的事务相同的方式使用锁定。“并发”部分意味着字典将继续在多个线程中正确运行。
并发集合中内置了 TryGetValue 和 TryRemove,它们承认有人可能会先删除一个项目。粒度级别的锁定是内置的,但您仍然需要考虑在这些情况下该怎么做。对于缓存,它通常并不重要——即它是一个幂等操作。
回复:缓存。我觉得这取决于您在缓存中存储的内容+您正在使用它做什么。有与使用对象相关的铸造成本。可能对于大多数基于 Web 的事物,MemCache 更适合上面的建议。