删除和添加多个项目时锁定 ConcurrentDictionary?
Lock ConcurrentDictionary while removing and adding multiple items?
我在 Whosebug 上阅读了以下文章:ConcurrentBag - Add Multiple Items? and Concurrent Dictionary Correct Usage 但答案对我来说仍然不是很明显。
我有这种情况:我在数据库中有 Leaderboard
table 并且我会定期更新它。为了优化服务器,我缓存了结果,所以我使用了 ConcurrentDictionary(因为有不同类型的排行榜,例如全时、3 天、7 天等...)。
这是我在更新排行榜上的代码:
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
原子中创建多个项目或操作。
我在 Whosebug 上阅读了以下文章:ConcurrentBag - Add Multiple Items? and Concurrent Dictionary Correct Usage 但答案对我来说仍然不是很明显。
我有这种情况:我在数据库中有 Leaderboard
table 并且我会定期更新它。为了优化服务器,我缓存了结果,所以我使用了 ConcurrentDictionary(因为有不同类型的排行榜,例如全时、3 天、7 天等...)。
这是我在更新排行榜上的代码:
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
原子中创建多个项目或操作。