【发布时间】:2015-03-21 11:51:49
【问题描述】:
我想要一些关于在哪里可以改进或更改当前代码的设计的建议。
有一个 Manager 类已设置,并有一个由不同线程调用的 Calculation 方法。每个线程都有一个需要计算的资源。这些资源可能属于不同的公司。 对于每个公司,我们都想缓存一些数据,但是我们只能在调用Calculate方法时通过资源获取公司数据。
所以我目前的想法是在Manager类中有一个Dictionary,以companyResourceTag为Key。 调用Calculate时,确定companyResourceTag并调用方法CheckCachedData。
private void CheckCachedData(int companyResourceTag)
{
_ReaderWriterLock.EnterUpgradeableReadLock();
try
{
if (!_CompanyCachedData.ContainsKey(companyResourceTag))
{
Elements elements = ElementService.GetAllElements();
DataElements dataElements = ElementService.GetAllDataElements();
CalendarGroupings calendarGroupings = CalendarService.GetAllCalendarGroupings();
CachedDataContainer cachedItem = new CachedDataContainer(elements, dataElements, calendarGroupings);
_ReaderWriterLock.EnterWriteLock();
try
{
_CompanyCachedData.Add(companyResourceTag, cachedItem);
}
finally
{
_ReaderWriterLock.ExitWriteLock();
}
}
}
finally
{
_ReaderWriterLock.ExitUpgradeableReadLock();
}
}
如果以前没有来自该公司的资源,则必须通过服务获取该公司的数据。基础表不会经常更改,我们可以假设在为所有资源运行计算期间这些表将保持不变。但是,获取这些数据非常耗时。因此需要缓存。
可能需要计算 100 家不同的公司和 30000 多种资源。还有一些其他地方(每个资源)可以读取此缓存数据,例如:
_ReaderWriterLock.EnterReadLock();
try
{
_CompanyCachedData.TryGetValue(companyResourceTag, out cachedDataContainer);
}
finally
{
_ReaderWriterLock.ExitReadLock();
}
//Do something with cachedDataContainer
因为 Eric Lathrop 在这里的评论,我没有尝试让代码更优雅: Possible problem
我没有使用 ConcurrentDictionary,因为这里提到的问题:Possible problem with ConcurrentDictionary
我不确定普通锁是否比 ReaderWriterLockSlim 更好,但我喜欢一次可以有多个读取器的想法,并且我可以升级锁。目前我也更关心正确性而不是速度。
我是否正确使用了 RWLS? 你同意我目前对 UpgradeableReadLock 的使用吗? 你同意我不使用 ConcurrentDictionary 的选择吗?
【问题讨论】:
-
“如果我想提高速度”——意思是什么?如果没有明确说明观察到的性能问题,以及明确说明的性能目标,那么这个问题就太宽泛了。您有什么证据表明您现在拥有的代码还不够快?鉴于您总是有可能必须通过网络获取数据,并且这种延迟是可以接受的,很难相信即使是一个简单的锁也会导致任何真正的问题。如果 RWLS 有效,您在这里有什么具体问题?
-
@Peter Duniho:我已经编辑了原始帖子以便更具体。
标签: c# multithreading caching dictionary