在删除和添加多个项时锁定ConcurrentDictionary
本文关键字:锁定 ConcurrentDictionary 删除 添加 | 更新日期: 2023-09-27 18:01:40
我在StackOverflow上阅读了以下文章:ConcurrentBag -添加多个项目?和并发字典正确用法,但答案对我来说仍然不明显。
我有这样的场景:我在数据库中有Leaderboard
表,我定期更新它。为了优化服务器,我缓存了结果,所以我使用了ConcurrentDictionary(因为有不同类型的排行榜,如All-time, 3-days, 7-days等)。
这是我在更新排行榜上的代码:
var leaderboards = business.UpdateLeaderboard(LeaderboardUpdater.LeaderboardDaySpans, LeaderboardUpdater.LeaderboardCount);
this.LastUpdateTime = now;
// The LeaderboardCache is ConcurrentDictionary<int, LeaderboardResponseViewModel>
this.LeaderboardCache.Clear();
foreach (var leaderboard in leaderboards)
{
this.LeaderboardCache.TryAdd(leaderboard.DaySpan, new LeaderboardResponseViewModel(leaderboard));
}
假设用户可以随时请求排行榜信息。所以我有一些问题:
- 我应该使用
Concat
而不是foreach
来确保所有项目同时添加吗? - 即使我使用
Concat
,我怎么能确保用户不会在Clear
和Concat
方法的中间请求? 我应该应用一个额外的锁吗?如果是这样,我如何确保并发读取,因为多个读取在同一时间是可以的?
您在错误的级别管理并发性。显然,您希望自动处理字典内容,但您在项目级别同步(不成功)。
使用以下数据结构:
volatile Lazy<...> myCache = new Lazy<Dictionary<...>>(ProduceCacheValues);
当您想刷新缓存值时,创建一个新的Lazy
并覆盖myCache
。
或者,只使用锁。对于低频短时间的操作来说,这通常已经足够好了。
需要说明的是,没有办法在一个ConcurrentDictionary
原子中创建多个项或操作。