下面的类为每个注册的新“ dataKey”引发一个事件,并在注销“ dataKey”并对该“ dataKey为零”计数时引发一个事件。
此类旨在确保线程安全,我正在尝试使其尽可能地具有性能。
我的问题是;我可以在Deregister方法中以某种方式删除第二次查询(更新_data [dataKey] = currentCountValue;)吗?
我不能简单地更新currentCountValue变量,因为该值仅在本地堆栈上而不是在Dictionary中更新。
还是可以建议您改善任何性能?我认为我无法删除锁并使用CAS操作(互锁方法)来更新计数,因为像这样使用字典时,字典对于更新不是线程安全的……是吗?
/我正在使用c#3.0。
谢谢你的时间。
public sealed class DataCounter
{
public event EventHandler NewKeyEvent;
public event EventHandler ZeroCountEvent;
private readonly Dictionary<string, int> _data = new Dictionary<string, int>();
public void Register(string dataKey)
{
lock (_data)
{
if (_data.ContainsKey(dataKey))
{
_data[dataKey]++;
}
else
{
_data.Add(dataKey, 1);
if (NewKeyEvent != null) NewKeyEvent(this, null);
}
}
}
public void Deregister(string dataKey)
{
lock (_data)
{
int currentCountValue;
if (_data.TryGetValue(dataKey, out currentCountValue))
{
if (currentCountValue > 0)
{
currentCountValue--;
_data[dataKey] = currentCountValue;
}
if (currentCountValue == 0)
{
if (ZeroCountEvent != null) ZeroCountEvent(this, null);
}
}
}
}
}
最佳答案
想一想-如果您不想通过索引器进行“设置”,可以将计数器移到类上吗?
class CounterBox {
public int Count {get;set;}
}
然后有一个
Dictionary<string,CounterBox>
。现在,您可以在词典外部更新Count
,并且仅当Remove(dataKey)
为零时才调用.Count
。这将有一个额外的取消引用,但您不必通过索引器进行分配。至于哪个更快:您需要分析。
就像是:
public sealed class DataCounter
{
private class CounterBox
{
public int Count { get; set; }
}
public event EventHandler NewKeyEvent;
public event EventHandler ZeroCountEvent;
private readonly Dictionary<string, CounterBox> _data
= new Dictionary<string, CounterBox>();
public void Register(string dataKey)
{
lock (_data)
{
CounterBox box;
if (_data.TryGetValue(dataKey, out box))
{
box.Count++;
}
else
{
_data.Add(dataKey, new CounterBox { Count = 1 });
EventHandler handler = NewKeyEvent;
if (handler != null) handler(this, EventArgs.Empty);
}
}
}
public void Deregister(string dataKey)
{
lock (_data)
{
CounterBox box;
if (_data.TryGetValue(dataKey, out box))
{
if (box.Count > 0)
{
box.Count--;
}
if (box.Count == 0)
{
EventHandler handler = ZeroCountEvent;
if (handler != null) handler(this, EventArgs.Empty);
_data.Remove(dataKey);
}
}
}
}
}
关于c# - 值类型和字典检索,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/847484/