下面的类为每个注册的新“ 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/

10-09 08:44