Ric*_*ick 6 .net multithreading dictionary locking try-catch
我有一个通用的词典,我用它作为线程.NET项目(C#)中的缓存.我将在字典上进行大量读取(在高峰时间可能每秒数百或更多).
我有一个简单的Get(int id)方法,如果它在缓存中,则返回一个CustomObject,否则返回null.
我的问题:锁定字典更快/更有效,还是只使用try/catch块?
假设字典存储在名为"dic"的变量中.
锁定样本:
public CustomObject Get(int id)
{
lock(dic)
{
if (dic.ContainsKey(id))
return dic[id];
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
试试/抓住样本:
public CustomObject Get(int id)
{
try
{
return dic[id];
}
catch
{
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
我认为你应该在自己的环境中测试它.基本上:
所以现在的问题是,你有多少次期望有缓存缺失,因此会抛出异常.我会选择lock(),因为它的执行时间不依赖于你是否会得到缓存命中,这意味着它更可预测和可测量,同时仍然非常便宜.我不认为每秒数百次点击会有任何问题.
我做的简单测试表明,使用try/catch获取缓存失败是非常非常昂贵的.
编辑:
简单测试表明:
这意味着,获得了lock(),因为它比try/catch更有效,如果你每几千次尝试获得超过1次缓存未命中,并且它更加稳定,不依赖于运气.
您可以继续并注销try-catch选项.我不知道它是否更慢,但我知道如果有另一个线程更新,它将不会总是产生正确,一致和可预测的结果Dictionary.问题在于,在某些时候,作者将Dictionary处于半生不熟的状态,而且没有人知道读者会看到什么.这不行.
选项1:如果您可以使用.NET 4.0,那么我会使用ConcurrentDictionary.
选项2:如果您使用的是.NET 3.5,则可以下载Reactive Extensions backport.ConcurrentDictionary包含在System.Threading.dll中.
选项3:另一个想法是保留两个单独的副本Dictionary.一个只用于阅读,而另一个用作接受更新的官方副本.无论何时更新"官方",Dictionary您都会克隆它并覆盖副本的引用.
public class Example
{
// This is the official version which can accept updates.
private readonly Dictionary<int, CustomObject> official = new Dictionary<int, CustomObject>();
// This is a readonly copy. This must be marked as volatile for this to work correctly.
private volatile Dictionary<int, CustomObject> copy = new Dictionary<int, CustomObject>();
public class Example()
{
}
public void Set(int id, CustomObject value)
{
lock (official)
{
// Update the official dictionary.
official[id] = value;
// Now create a clone of the official dictionary.
var clone = new Dictionary<int, CustomObject>();
foreach (var kvp in official)
{
clone.Add(kvp.Key, kvp.Value);
}
// Swap out the reference.
copy = clone;
}
}
public CustomObject Get(int id)
{
// No lock is required here.
CustomObject value = null;
if (copy.TryGetValue(id, out value))
{
return value;
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
如果有很多项目Dictionary或者如果经常发生官方副本的更新,则此选项不能正常工作.但是,这是我不时使用的一个技巧.
方案4:同样合理的方法是坚持使用普通的老方法lock.
| 归档时间: |
|
| 查看次数: |
689 次 |
| 最近记录: |