using System.Collections.Generic;
using System.Threading;

namespace CSharpUtilHelpV2
{
    /// <summary>
    /// 基于.NET 2.0的对于Dictionary线程安全操作工具类
    /// 说明
    /// 默认读锁超时1000毫秒
    /// 默认写锁超时1000毫秒
    /// .NET 4.0 可以使用ConcurrentDictionary来实现。
    /// </summary>
    /// <typeparam name="T">泛型</typeparam>
    public class ThreadSafeDictionaryV2<T>
    {
        /*参考资料
         * 1.
         * 使用Monitor或Mutex进行同步控制的问题:由于独占访问模型不允许任何形式的并发访问,这样的效率总是不太高。
         * 许多时候,应用程序在访问资源时是进行读操作,写操作相对较少。为解决这一问题,
         * C#提供了System.Threading.ReaderWriterLock类以适应多用户读/单用户写的场景。该类可实现以下功能:
         * 如果资源未被写操作锁定,那么任何线程都可对该资源进行读操作锁定,并且对读操作锁数量没有限制,即多个线程可同时对该资源进行读操作锁定,以读取数据。
         * 如果资源未被添加任何读或写操作锁,那么一个且仅有一个线程可对该资源添加写操作锁定,以写入数据。简单的讲就是:读操作锁是共享锁,允许多个线程同时读取数据;
         * 写操作锁是独占锁,同一时刻,仅允许一个线程进行写操作。
         * 引用链接:http://www.csharpwin.com/dotnetspace/12761r5814.shtml
         *
         * 2.
         * ReaderWriterLock 用于同步对资源的访问。在任一特定时刻,它允许多个线程同时进行读访问,或者允许单个线程进行写访问。
         * 在资源不经常发生更改的情况下,ReaderWriterLock 所提供的吞吐量比简单的一次只允许一个线程的锁(如 Monitor)更高。
         * 在多数访问为读访问,而写访问频率较低、持续时间也比较短的情况下,ReaderWriterLock 的性能最好。
         * 多个读线程与单个写线程交替进行操作,所以读线程和写线程都不会长时间阻止。
         * 大多数在 ReaderWriterLock 上获取锁的方法都采用超时值。使用超时可以避免应用程序中出现死锁。
         * 如果不使用超时,这两个线程将出现死锁。
         * 引用链接:http://msdn.microsoft.com/zh-cn/library/system.threading.readerwriterlock(v=vs.80).aspx
         *
         * 3.其他链接
         * http://tinythreadsafecache.codeplex.com/SourceControl/latest#TinyThreadSafeCache.cs
         * http://www.grumpydev.com/2010/02/25/thread-safe-dictionarytkeytvalue/
         * http://stackoverflow.com/questions/157933/whats-the-best-way-of-implementing-a-thread-safe-dictionary
         * http://stackoverflow.com/questions/15095817/adding-to-a-generic-dictionary-causes-indexoutofrangeexception
         */

        ReaderWriterLock rwlock = new ReaderWriterLock();//声明读写锁 .NET 3.5+ 推荐用ReaderWriterLockSlim
        Dictionary<string, T> dic = new Dictionary<string, T>();//Dictionary
        static int readerTimeout = 1000;//默认读锁超时1000毫秒
        static int writerTimeout = 1000;//默认写锁超时1000毫秒
        /// <summary>
        /// 默认构造函数
        /// </summary>
        public ThreadSafeDictionaryV2()
        {

        }
        /// <summary>
        /// 带参构造函数
        /// </summary>
        /// <param name="_readerTimeout">读锁超时设置【单位毫秒】</param>
        /// <param name="_writerTimeout">写锁超时设置【单位毫秒】</param>
        public ThreadSafeDictionaryV2(int _readerTimeout, int _writerTimeout)
        {
            readerTimeout = _readerTimeout;
            writerTimeout = _writerTimeout;
        }
        /// <summary>
        /// This【线程安全】
        /// </summary>
        /// <param name="key">键</param>
        /// <returns>值</returns>
        public T this[string key]
        {
            get
            {
                rwlock.AcquireReaderLock(readerTimeout);
                try
                {
                    return dic[key];
                }
                finally
                {
                    rwlock.ReleaseReaderLock();
                }
            }
            set
            {
                rwlock.AcquireWriterLock(writerTimeout);
                try
                {
                    dic[key] = value;
                }
                finally
                {
                    rwlock.ReleaseWriterLock();
                }
            }
        }

        /// <summary>
        /// Add【线程安全】
        /// 默认超时1000毫秒
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="val">值</param>
        public void Add(string key, T val)
        {
            Add(key, val, writerTimeout);
        }
        /// <summary>
        /// Add【线程安全】
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="val">值</param>
        /// <param name="timeout">超时设置【毫秒】</param>
        public void Add(string key, T val, int timeout)
        {
            rwlock.AcquireWriterLock(timeout);
            try
            {
                dic[key] = val;
            }
            finally
            {
                rwlock.ReleaseWriterLock();
            }
        }
        /// <summary>
        /// Get【线程安全】
        /// 默认超时1000毫秒
        /// </summary>
        /// <param name="key">键</param>
        /// <returns>值</returns>
        public T Get(string key)
        {
            return Get(key, readerTimeout);
        }
        /// <summary>
        /// Get【线程安全】
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="timeout">超时设置【毫秒】</param>
        /// <returns>值</returns>
        public T Get(string key, int timeout)
        {
            rwlock.AcquireReaderLock(timeout);
            try
            {
                T val;
                dic.TryGetValue(key, out val);
                return val;
            }
            finally
            {
                rwlock.ReleaseReaderLock();
            }
        }
        /// <summary>
        /// Remove【线程安全】
        /// 默认超时1000毫秒
        /// </summary>
        /// <param name="key">键</param>
        public void Remove(string key)
        {
            Remove(key, writerTimeout);
        }
        /// <summary>
        /// Remove【线程安全】
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="timeout">超时设置【毫秒】</param>
        public void Remove(string key, int timeout)
        {
            rwlock.AcquireWriterLock(timeout);
            try
            {
                dic.Remove(key);
            }
            finally
            {
                rwlock.ReleaseWriterLock();
            }
        }
        /// <summary>
        /// Clear【线程安全】
        /// 默认超时1000毫秒
        /// </summary>
        public void Clear()
        {
            Clear(writerTimeout);
        }
        /// <summary>
        /// Clear【线程安全】
        /// </summary>
        /// <param name="timeout">超时设置【毫秒】</param>
        public void Clear(int timeout)
        {
            rwlock.AcquireWriterLock(timeout);
            try
            {
                dic.Clear();
            }
            finally
            {
                rwlock.ReleaseWriterLock();
            }
        }
        /// <summary>
        /// ContainsKey【线程安全】
        /// 默认超时1000毫秒
        /// </summary>
        /// <param name="key">键</param>
        /// <returns>是否包含</returns>
        public bool ContainsKey(string key)
        {
            return ContainsKey(key, readerTimeout);
        }
        /// <summary>
        /// ContainsKey【线程安全】
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="timeout">超时设置【毫秒】</param>
        /// <returns>是否包含</returns>
        public bool ContainsKey(string key, int timeout)
        {
            rwlock.AcquireReaderLock(timeout);
            try
            {
                return dic.ContainsKey(key);
            }
            finally
            {
                rwlock.ReleaseReaderLock();
            }
        }
        /// <summary>
        /// Count【线程安全】
        /// 默认超时1000毫秒
        /// </summary>
        /// <returns></returns>
        public int Count()
        {
            return Count(readerTimeout);
        }
        /// <summary>
        /// Count【线程安全】
        /// </summary>
        /// <param name="timeout">超时设置【毫秒】</param>
        /// <returns>Count</returns>
        public int Count(int timeout)
        {
            rwlock.AcquireReaderLock(timeout);
            try
            {
                return dic.Count;
            }
            finally
            {
                rwlock.ReleaseReaderLock();
            }
        }
    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

[C#]Thread Safe Dictionary in .NET 2.0的更多相关文章

  1. 【转】php Thread Safe(线程安全)和None Thread Safe(NTS,非 线程安全)之分

    Windows版的PHP从版本5.2.1开始有Thread Safe(线程安全)和None Thread Safe(NTS,非线程安全)之分,这两者不同在于何处?到底应该用哪种?这里做一个简单的介绍. ...

  2. PHP版本VC6与VC9、Thread Safe与None-Thread Safe等的区别

    PHP版本VC6与VC9.Thread Safe与None-Thread Safe等的区别 [摘要]PHP 是一种 HTML 内嵌式的语言,是一种在服务器端执行的嵌入HTML文档的脚本语言,在PHP发 ...

  3. Thread Safe(线程安全)和None Thread Safe(NTS,非线程安全)之分

    Windows版的PHP从版本5.2.1开始有Thread Safe(线程安全)和None Thread Safe(NTS,非线程安全)之分,这两者不同在于何处?到底应该用哪种?这里做一个简单的介绍. ...

  4. PHP的(Thread Safe与Non Thread Safe)

    在安装xdebug到时候你会有有TS和NTS版本的选择,在以前还有VC6和VC9的版本.如果你没有根据你目前的服务器的状况选择对应的版本的话,那么xdebug是安装不成功的. 一.如何选择 php5. ...

  5. PHP版本VC6与VC9/VC11/VC14、Thread Safe与None-Thread Safe等的区别

    最近正好在弄一个PHP的程序,在这之前一直没有怎么以接触,发现对PHP版本知识了解不是很清楚,自己看了不少类似的文章,还是感觉不够明确和全面, 网上的结论又都是模棱两可,在此,给出最完整甚至武断的解释 ...

  6. windows zend_guard+apache no ssl+php no Thread Safe fastcgi模式 环境配置

    最近公司要做代码加密,就采用ZEND GUARD 方式加密代码 并进行显示 此文为总结,以备自己以后查看和给需要的同学们参考 采用的php为5.3版本  由于现在加密的更改, 能支持zend guar ...

  7. PHP关于VC9和VC6以及Thread Safe和Non Thread Safe版本选择的问题

    一.如何选择PHP5.3的VC9版本和VC6版本 VC6版本是使用Visual Studio 6编译器编译的,如果你的PHP是用Apache来架设的,那你就选择VC6版本.      VC9版本是使用 ...

  8. PHP关于VC11,VC9,VC6以及Thread Safe和Non Thread Safe版本选择的问题

    这里是我在搭建php环境时收集的资料供大家参考: 现在PHP官网上下载PHP安装包都有VC11或VC9的字样,这是什么含义,我们应该下载哪种安装包更好呢?其实PHP官网给出了答案: VC6版本是使用V ...

  9. PHP版本VC6和VC9、Non Thread Safe和Thread Safe的区别

    链接:http://www.cnblogs.com/neve/articles/1863853.html 想更新个PHP的版本,PHP的windows版本已经分离出来了,见http://windows ...

随机推荐

  1. win7下禁用ctrl alt del +上下左右键

    1.控制面板 2.屏幕分辨率 3.高级设置 4.英特尔图形和媒体控制面板 5.图形属性 6.选项和支持 7.快捷键管理器 8.去掉启动前的勾

  2. oc学习之路----代理模式2-使用步骤

    之前已经写过一个个人关于代理模式的一些看法,现在就来总结一下使用代理模式的步骤吧. 1.先搞清楚谁是谁的代理(delegate) ● 2.定义代理协议,协议名称的命名规范:控件类名 + Delegat ...

  3. iOS 火星坐标相关整理及解决方案汇总(转)

    这几天在处理定位相关的代码,彻彻底底的被火星坐标恶心到了. 恶心列表 从 CLLocationManager 取出来的经纬度放到 mapView 上显示,是错的! 从 CLLocationManage ...

  4. 为一张PCI卡打通经络的过程

    一张PCI卡通过“一转二”的转接卡插在主板上,probe调用失败,日志显示读取配置空间的时候发生了奇偶校验错误,可是使用相同的转接卡把它插在另外一台相同机器的主板上时,却运行正常,这就说明不是转接卡的 ...

  5. CCLabelAtlas创建自定义字体

    有时候游戏中要用到一些特殊的字体效果,特别是数字. CCLabelAtlas就可以从png图中读取文字. CCLabelAtlas* diceCount=CCLabelAtlas::labelWith ...

  6. 音频播放AVFoundation框架

    一.系统声音 ios应用中的提醒声音.游戏背景音乐等.可以播放的格式有CAF.AIF.WAV. 系统声音服务提供了一个API,但是没有操作声音和控制音量的功能,因此如果为多媒体或者游戏创建专门的声音, ...

  7. Android(java)学习笔记211:采用httpclient提交数据(qq登录案例)

    1.Apache -Httpclient HttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的.最新的.功能丰富的支持 HTTP 协议的客户端编程工具包 ...

  8. 【Python】分布式任务队列Celery使用参考资料

    Python-Celery Homepage | Celery: Distributed Task Queue User Guide - Celery 4.0.2 documentation Task ...

  9. Java对象与Json之间的转换

    使用Jackson的ObjectMapper对象的readValue和writeValueAsString方法可以进行转换. 对于简单基本类型或String类型的对象,使用上述方法可以满足. 但是如果 ...

  10. Git之路--1

    昨天下午到今天早上,终于搞定了github.过程很难过,不过看到自己的github上有代码了.还是小小的开心了一下.暂时没时间分享相关技术,附带微博链接,有想试试上传上Github的小伙伴可以查看我的 ...