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. apache安装php7过程中遇到到段错误

    1.假如apache的配置文件httpd.conf同时加载libphp5.so和libphp7.so 2.如图所示,modules下同时存在libphp5.so/libphp7.so 3.启动apac ...

  2. android httpClient 支持HTTPS的2种处理方式

    摘自: http://www.kankanews.com/ICkengine/archives/9634.shtml 项目中Android https或http请求地址重定向为HTTPS的地址,相信很 ...

  3. Hyper-V性能-CPU分配

    为新部署的微软Hyper-V环境中的主机和网络挑选合适的硬件并非易事,更不用说在生产环境中衡量和监控性能这项任务了.在这里,我和大家谈谈服务器的核心CPU与Hyper-V的结合是如何相得益彰的. 我接 ...

  4. mysql查询语句举例

    1. 基础数据表 学生成绩表(stuscore): 姓名:name 课程:subject 分数:score 学号:stuid 张三 数学 89 1 张三 语文 80 1 张三 英语 70 1 李四 数 ...

  5. python中的对象拷贝

    python中.进行函数參数传递或者返回值时,假设是一般的变量,会拷贝传递.假设是列表或字典则是引用传递.那python怎样对列表和字典进行拷贝传递呢:标准库的copy模块提供了两个方法:copy和d ...

  6. play wav sound

    播放 WAV文件             string s = @"D:\Administrator\安装文件\完美世界国际版\patcher\skin\sounds\click.wav&q ...

  7. Ubuntu16.04/windows7修改本地hosts文件

    1. 从github上下载最新的hosts文件:https://serve.netsh.org/pub/ipv4-hosts/ ubuntu16.04: 第二步:Ctrl+Alt+T 打开ubuntu ...

  8. asp.net下载的方法

    public void DownLoad( ){ string filePath = Server.MapPath( @"\UserFile\" );//这里注意了,你得指明要下载 ...

  9. 读取group by 之外的字段

    序号 姓名 性别 身高 1 张三 男  185 2 李四 女  161 3 王五 女  166 4 赵六 男  178 1.获取男生女生人数 select count(性别) , 性别 from 表名 ...

  10. Atom编辑器入门到精通(二) 插件的安装和管理

    在本节中我们会学习如果安装和使用插件插件是Atom中一个非常重要的组成部分,很多功能都是以插件形式存在的.比如上篇文章中提到的目录树和设置等窗口都是通过默认安装的插件来实现的. 查看已安装的插件 打开 ...