线程安全SortedDictionary [英] Thread safe SortedDictionary

查看:220
本文介绍了线程安全SortedDictionary的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个使用SortedDictionary来存储和操作数据的类。除了在多线程环境中实现该类之外,该类也很好用。现在,我想通过为内部SortedDictionary类编写一个包装类来使类线程安全。我想使用Reader-Writer Lock来实现这一点,但现在我只是在编写包装类本身时遇到问题。具体来说,我不知道如何实现字典的枚举器。这是我现在完成的类的完整代码。

  public class ConcurrentSortedDictionary< TKey,TValue> :IEnumerable< KeyValuePair< TKey,TValue>> 
{
#region变量

SortedDictionary< TKey,TValue> _dict;

#endregion

#region构造函数

public ConcurrentSortedDictionary()
{
_dict = new SortedDictionary< TKey,TValue> ;();
}

public ConcurrentSortedDictionary(IComparer< TKey> comparer)
{
_dict = new SortedDictionary< TKey,TValue>(comparer);
}

public ConcurrentSortedDictionary(IDictionary< TKey,TValue>字典)
{
_dict = new SortedDictionary< TKey,TValue&


public ConcurrentSortedDictionary(IDictionary< TKey,TValue>字典,IComparer&TK; 比较器)
{
_dict = new SortedDictionary< TKey,TValue& ,比较)
}

#endregion

#region属性

public IComparer< TKey> Comparer
{
get
{
return _dict.Comparer;
}
}

public int Count
{
get
{
return _dict.Count;
}
}

public TValue this [TKey key]
{
get
{
return _dict [key];
}

set
{
_dict [key] = value;
}
}

public SortedDictionary< TKey,TValue> .KeyCollection Keys
{
get
{
return new SortedDictionary< ; TKEY的,TValue> .KeyCollection(_dict);
}
}

public SortedDictionary< TKey,TValue> .ValueCollection值
{
get
{
返回新的SortedDictionary< ; TKey,TValue> .ValueCollection(_dict);
}
}

#endregion

#region方法

public void Add(TKey key,TValue value)
{
_dict.Add(key,value);
}

public void Clear()
{
_dict.Clear();
}

public bool ContainsKey(TKey key)
{
return _dict.ContainsKey(key);
}

public bool ContainsValue(TValue value)
{
return _dict.ContainsValue(value);
}

public void CopyTo(KeyValuePair< TKey,TValue> [] array,int index)
{
_dict.CopyTo(array,index);
}

public override bool Equals(Object obj)
{
return _dict.Equals(obj);
}

IEnumerator< KeyValuePair< TKey,TValue>> IEnumerable< KeyValuePair  TKey,TValue> .GetEnumerator()
{
return GetEnumerator();
}

public IEnumerator< KeyValuePair< TKey,TValue>> GetEnumerator()
{
return _dict.GetEnumerator();
}

public override int GetHashCode()
{
return _dict.GetHashCode();
}

public bool删除(TKey键)
{
return _dict.Remove(key);
}

public override string ToString()
{
return _dict.ToString();
}

public bool TryGetValue(TKey key,out TValue value)
{
return _dict.TryGetValue(key,out value);
}

#endregion
}

我编译代码,我收到错误消息:


'ConcurrentSortedDictionary'不实现接口
成员'System.Collections。 IEnumerable.GetEnumerator()。
'ConcurrentSortedDictionary.GetEnumerator()'不能
实现'System.Collections.IEnumerable.GetEnumerator()',因为
没有匹配的返回类型
'System.Collections .Intumerator'。


我看过这里的几个帖子作为参考:



如何我在我的Dictionary包装器类中实现IEnumerable,实现IEnumerable< Foo>?
什么是实现线程安全词典的最佳方法?



但是我看不到什么我做错了非常感谢任何帮助,谢谢!



Jason O

解决方案

执行dvnrrs的建议,我现在班上班很好。我甚至为IEnumerable接口添加了一个包装类来保护SortedDictionary的枚举(从这个示例修改的代码如下: http://www.codeproject.com/Articles/56575/Thread-safe-enumeration-in-C )。以下是包含读写器锁的更新代码:

  using System; 
使用System.Collections.Generic;
使用System.Linq;
使用System.Text;
使用System.Collections;
使用System.Threading;

public class SafeEnumerator< T> :IEnumerator< T>
{
#region变量

//这是(线程不安全的)
//枚举的底层集合
private readonly IEnumerator< T> ; _enumerator;

//这是我们要锁定的对象。
private ReaderWriterLockSlim _lock;

#endregion

#region构造函数

public SafeEnumerator(IEnumerator< T>内部,ReaderWriterLockSlim readWriteLock)
{
_enumerator = inner;
_lock = readWriteLock;

//在构造函数中输入
_lock.EnterReadLock();
}

#endregion

#region实现IDisposable

public void Dispose()
{
// ..并退出锁定Dispose()
//当foreach循环完成
_lock.ExitReadLock()时,这将被调用;
}

#endregion

#region实现IEnumerator

//我们只是将实际的实现
//内部枚举器,实际上迭代
//超过一些集合

public bool MoveNext()
{
return _enumerator.MoveNext();
}

public void Reset()
{
_enumerator.Reset();
}

public T当前
{
get
{
return _enumerator.Current;
}
}

对象IEnumerator.Current
{
get
{
return Current;
}
}

#endregion
}

public class ConcurrentSortedDictionary&TK,TValue> :IEnumerable< KeyValuePair< TKey,TValue>>
{
#region变量

private ReaderWriterLockSlim _readWriteLock = new ReaderWriterLockSlim();
SortedDictionary< TKey,TValue> _dict;

#endregion

#region构造函数

public ConcurrentSortedDictionary()
{
_dict = new SortedDictionary< TKey,TValue> ;();
}

public ConcurrentSortedDictionary(IComparer< TKey> comparer)
{
_dict = new SortedDictionary< TKey,TValue>(comparer);
}

public ConcurrentSortedDictionary(IDictionary< TKey,TValue>字典)
{
_dict = new SortedDictionary< TKey,TValue&


public ConcurrentSortedDictionary(IDictionary< TKey,TValue>字典,IComparer&TK; 比较器)
{
_dict = new SortedDictionary< TKey,TValue& ,比较)
}

#endregion

#region属性

public IComparer< TKey> Compars
{
get
{
_readWriteLock.EnterReadLock();
try
{
return _dict.Comparer;
}
finally
{
_readWriteLock.ExitReadLock();
}
}
}

public int Count
{
get
{
_readWriteLock.EnterReadLock() ;
try
{
return _dict.Count;
}
finally
{
_readWriteLock.ExitReadLock();
}
}
}

public TValue这个[TKey key]
{
get
{
_readWriteLock .EnterReadLock();
try
{
return _dict [key];
}
finally
{
_readWriteLock.ExitReadLock();
}
}
set
{
_readWriteLock.EnterWriteLock();
try
{
_dict [key] = value;
}
finally
{
_readWriteLock.ExitWriteLock();
}
}
}

public SortedDictionary< TKey,TValue> .KeyCollection Keys
{
get
{
_readWriteLock.EnterReadLock();
try
{
返回新的SortedDictionary< TKey,TValue> .KeyCollection(_dict);
}
finally
{
_readWriteLock.ExitReadLock();
}
}
}

public SortedDictionary< TKey,TValue> .ValueCollection值
{
get
{
_readWriteLock.EnterReadLock();
try
{
return new SortedDictionary< TKey,TValue> .ValueCollection(_dict);
}
finally
{
_readWriteLock.ExitReadLock();
}
}
}

#endregion

#region方法

public void Add(TKey key ,TValue值)
{
_readWriteLock.EnterWriteLock();
try
{
_dict.Add(key,value);
}
finally
{
_readWriteLock.ExitWriteLock();
}
}

public void Clear()
{
_readWriteLock.EnterWriteLock();
try
{
_dict.Clear();
}
终于
{
_readWriteLock.ExitWriteLock();
}
}

public bool ContainsKey(TKey key)
{
_readWriteLock.EnterReadLock();
try
{
return _dict.ContainsKey(key);
}
finally
{
_readWriteLock.ExitReadLock();
}
}

public bool ContainsValue(TValue value)
{
_readWriteLock.EnterReadLock();
try
{
return _dict.ContainsValue(value);
}
finally
{
_readWriteLock.ExitReadLock();
}
}

public void CopyTo(KeyValuePair< TKey,TValue> []数组,int索引)
{
_readWriteLock.EnterReadLock();
try
{
_dict.CopyTo(array,index);
}
finally
{
_readWriteLock.ExitReadLock();
}
}

public override bool Equals(Object obj)
{
_readWriteLock.EnterReadLock();
try
{
return _dict.Equals(obj);
}
finally
{
_readWriteLock.ExitReadLock();
}
}

public IEnumerator< KeyValuePair< TKey,TValue>> GetEnumerator()
{
返回新的SafeEnumerator< KeyValuePair< TKey,TValue>(_ dict.GetEnumerator(),_readWriteLock);


IEnumerator IEnumerable.GetEnumerator()
{
返回新的SafeEnumerator&KeyValuePair< TKey,TValue>(_ dict.GetEnumerator(),_readWriteLock);
}

public override int GetHashCode()
{
_readWriteLock.EnterReadLock();
try
{
return _dict.GetHashCode();
}
finally
{
_readWriteLock.ExitReadLock();
}
}

public bool删除(TKey键)
{
_readWriteLock.EnterWriteLock();
try
{
return _dict.Remove(key);
}
finally
{
_readWriteLock.ExitWriteLock();
}
}

public override string ToString()
{
_readWriteLock.EnterReadLock();
try
{
return _dict.ToString();
}
finally
{
_readWriteLock.ExitReadLock();
}
}

public bool TryGetValue(TKey key,out TValue value)
{
_readWriteLock.EnterReadLock();
try
{
return _dict.TryGetValue(key,out value);
}
finally
{
_readWriteLock.ExitReadLock();
}
}

#endregion
}


I made a class that uses a SortedDictionary to store and manipulate data. The class works great except when it is implemented in a multi-threaded environment. Now, I would like to make the class thread safe by writing a wrapper class for the internal SortedDictionary class. I would like to use the Reader-Writer Locks to implement this but for now, I'm having problems just writing the wrapper class itself. Specifically, I'm not sure how to implement the Enumerator for the dictionary. Here is my complete code for the class as it stands now.

    public class ConcurrentSortedDictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
{
    #region Variables

    SortedDictionary<TKey, TValue> _dict;

    #endregion

    #region Constructors

    public ConcurrentSortedDictionary()
    {
        _dict = new SortedDictionary<TKey, TValue>();
    }

    public ConcurrentSortedDictionary(IComparer<TKey> comparer)
    {
        _dict = new SortedDictionary<TKey, TValue>(comparer);
    }

    public ConcurrentSortedDictionary(IDictionary<TKey, TValue> dictionary)
    {
        _dict = new SortedDictionary<TKey, TValue>(dictionary);
    }

    public ConcurrentSortedDictionary(IDictionary<TKey, TValue> dictionary, IComparer<TKey> comparer)
    {
        _dict = new SortedDictionary<TKey, TValue>(dictionary, comparer);
    }

    #endregion

    #region Properties

    public IComparer<TKey> Comparer
    {
        get 
        { 
            return _dict.Comparer;
        }
    }

    public int Count
    {
        get
        {
            return _dict.Count;
        }
    }

    public TValue this[TKey key]
    { 
        get
        {
            return _dict[key];
        }

        set
        {
            _dict[key] = value;
        }
    }

    public SortedDictionary<TKey, TValue>.KeyCollection Keys
    {
        get
        {
            return new SortedDictionary<TKey,TValue>.KeyCollection(_dict);
        }
    }

    public SortedDictionary<TKey, TValue>.ValueCollection Values
    {
        get
        {
            return new SortedDictionary<TKey, TValue>.ValueCollection(_dict);
        }
    }

    #endregion

    #region Methods

    public void Add(TKey key, TValue value)
    {
        _dict.Add(key, value);
    }

    public void Clear()
    {
        _dict.Clear();
    }

    public bool ContainsKey(TKey key)
    {
        return _dict.ContainsKey(key);
    }

    public bool ContainsValue(TValue value)
    {
        return _dict.ContainsValue(value);
    }

    public void CopyTo(KeyValuePair<TKey, TValue>[] array, int index)
    {
        _dict.CopyTo(array, index);
    }

    public override bool Equals(Object obj)
    {
        return _dict.Equals(obj);
    }

    IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
    {
        return GetEnumerator();
    }

    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
    {
        return _dict.GetEnumerator();
    }

    public override int GetHashCode()
    {
        return _dict.GetHashCode();
    }

    public bool Remove(TKey key)
    {
        return _dict.Remove(key);
    }

    public override string ToString()
    {
        return _dict.ToString();
    }

    public bool TryGetValue(TKey key, out TValue value)
    {
        return _dict.TryGetValue(key, out value);
    }

    #endregion
}

When I compile the code, I get the error message:

'ConcurrentSortedDictionary' does not implement interface member 'System.Collections.IEnumerable.GetEnumerator()'. 'ConcurrentSortedDictionary.GetEnumerator()' cannot implement 'System.Collections.IEnumerable.GetEnumerator()' because it does not have the matching return type of 'System.Collections.IEnumerator'.

I looked at several posts here relating to this as a reference:

How do I implement IEnumerable in my Dictionary wrapper class that implements IEnumerable<Foo>? What's the best way of implementing a thread-safe Dictionary?

but I don't see what I'm doing wrong. Any assistance greatly appreciated, thanks!

Jason O

解决方案

After implementing the suggestion by dvnrrs, I now have the class working well. I even added a wrapper class for the IEnumerable interface to protect enumerations of the SortedDictionary (code modified from this example here: http://www.codeproject.com/Articles/56575/Thread-safe-enumeration-in-C). Here is the updated code with the Reader-Writer Locks included:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Threading;

public class SafeEnumerator<T> : IEnumerator<T>
{
    #region Variables

    // this is the (thread-unsafe)
    // enumerator of the underlying collection
    private readonly IEnumerator<T> _enumerator;

    // this is the object we shall lock on. 
    private ReaderWriterLockSlim _lock;

    #endregion 

    #region Constructor

    public SafeEnumerator(IEnumerator<T> inner, ReaderWriterLockSlim readWriteLock)
    {
        _enumerator = inner;
        _lock = readWriteLock;

        // Enter lock in constructor
        _lock.EnterReadLock();
    }

    #endregion

    #region Implementation of IDisposable

    public void Dispose()
    {
        // .. and exiting lock on Dispose()
        // This will be called when the foreach loop finishes
        _lock.ExitReadLock();
    }

    #endregion

    #region Implementation of IEnumerator

    // we just delegate actual implementation
    // to the inner enumerator, that actually iterates
    // over some collection

    public bool MoveNext()
    {
        return _enumerator.MoveNext();
    }

    public void Reset()
    {
        _enumerator.Reset();
    }

    public T Current
    {
        get 
        { 
            return _enumerator.Current; 
        }
    }

    object IEnumerator.Current
    {
        get 
        { 
            return Current; 
        }
    }

    #endregion
}

public class ConcurrentSortedDictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
{
    #region Variables

    private ReaderWriterLockSlim _readWriteLock = new ReaderWriterLockSlim();
    SortedDictionary<TKey, TValue> _dict;

    #endregion

    #region Constructors

    public ConcurrentSortedDictionary()
    {
        _dict = new SortedDictionary<TKey, TValue>();
    }

    public ConcurrentSortedDictionary(IComparer<TKey> comparer)
    {
        _dict = new SortedDictionary<TKey, TValue>(comparer);
    }

    public ConcurrentSortedDictionary(IDictionary<TKey, TValue> dictionary)
    {
        _dict = new SortedDictionary<TKey, TValue>(dictionary);
    }

    public ConcurrentSortedDictionary(IDictionary<TKey, TValue> dictionary, IComparer<TKey> comparer)
    {
        _dict = new SortedDictionary<TKey, TValue>(dictionary, comparer);
    }

    #endregion

    #region Properties

    public IComparer<TKey> Comparer
    {
        get 
        {
            _readWriteLock.EnterReadLock();
            try
            {
                return _dict.Comparer;
            }
            finally
            {
                _readWriteLock.ExitReadLock();
            }
        }
    }

    public int Count
    {
        get
        {
            _readWriteLock.EnterReadLock();
            try
            {
                return _dict.Count;
            }
            finally
            {
                _readWriteLock.ExitReadLock();
            }
        }
    }

    public TValue this[TKey key]
    { 
        get
        {
            _readWriteLock.EnterReadLock();
            try
            {
                return _dict[key];
            }
            finally
            {
                _readWriteLock.ExitReadLock();
            }
        }
        set
        {
            _readWriteLock.EnterWriteLock();
            try
            {
                _dict[key] = value;
            }
            finally
            {
                _readWriteLock.ExitWriteLock();
            }
        }
    }

    public SortedDictionary<TKey, TValue>.KeyCollection Keys
    {
        get
        {
            _readWriteLock.EnterReadLock();
            try
            {
                return new SortedDictionary<TKey, TValue>.KeyCollection(_dict);
            }
            finally
            {
                _readWriteLock.ExitReadLock();
            }
        }
    }

    public SortedDictionary<TKey, TValue>.ValueCollection Values
    {
        get
        {
            _readWriteLock.EnterReadLock();
            try
            {
                return new SortedDictionary<TKey, TValue>.ValueCollection(_dict);
            }
            finally
            {
                _readWriteLock.ExitReadLock();
            }
        }
    }

    #endregion

    #region Methods

    public void Add(TKey key, TValue value)
    {
        _readWriteLock.EnterWriteLock();
        try
        {
            _dict.Add(key, value);
        }
        finally
        {
            _readWriteLock.ExitWriteLock();
        }
    }

    public void Clear()
    {
        _readWriteLock.EnterWriteLock();
        try
        {
            _dict.Clear();
        }
        finally
        {
            _readWriteLock.ExitWriteLock();
        }
    }

    public bool ContainsKey(TKey key)
    {
        _readWriteLock.EnterReadLock();
        try
        {
            return _dict.ContainsKey(key);
        }
        finally
        {
            _readWriteLock.ExitReadLock();
        }
    }

    public bool ContainsValue(TValue value)
    {
        _readWriteLock.EnterReadLock();
        try
        {
            return _dict.ContainsValue(value);
        }
        finally
        {
            _readWriteLock.ExitReadLock();
        }
    }

    public void CopyTo(KeyValuePair<TKey, TValue>[] array, int index)
    {
        _readWriteLock.EnterReadLock();
        try
        {
            _dict.CopyTo(array, index);
        }
        finally
        {
            _readWriteLock.ExitReadLock();
        }
    }

    public override bool Equals(Object obj)
    {
        _readWriteLock.EnterReadLock();
        try
        {
            return _dict.Equals(obj);
        }
        finally
        {
            _readWriteLock.ExitReadLock();
        }
    }

    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
    {
        return new SafeEnumerator<KeyValuePair<TKey, TValue>>(_dict.GetEnumerator(), _readWriteLock);
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return new SafeEnumerator<KeyValuePair<TKey, TValue>>(_dict.GetEnumerator(), _readWriteLock);
    }

    public override int GetHashCode()
    {
        _readWriteLock.EnterReadLock();
        try
        {
            return _dict.GetHashCode();
        }
        finally
        {
            _readWriteLock.ExitReadLock();
        }
    }

    public bool Remove(TKey key)
    {
        _readWriteLock.EnterWriteLock();
        try
        {
            return _dict.Remove(key);
        }
        finally
        {
            _readWriteLock.ExitWriteLock();
        }
    }

    public override string ToString()
    {
        _readWriteLock.EnterReadLock();
        try
        {
            return _dict.ToString();
        }
        finally
        {
            _readWriteLock.ExitReadLock();
        }
    }

    public bool TryGetValue(TKey key, out TValue value)
    {
        _readWriteLock.EnterReadLock();
        try
        {
            return _dict.TryGetValue(key, out value);
        }
        finally
        {
            _readWriteLock.ExitReadLock();
        }
    }

    #endregion
}

这篇关于线程安全SortedDictionary的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆