惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

B
Blog RSS Feed
D
Darknet – Hacking Tools, Hacker News & Cyber Security
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
G
Google Developers Blog
MyScale Blog
MyScale Blog
Google DeepMind News
Google DeepMind News
J
Java Code Geeks
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
C
Check Point Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
P
Proofpoint News Feed
D
Docker
Jina AI
Jina AI
博客园 - 三生石上(FineUI控件)
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Help Net Security
Help Net Security
Google DeepMind News
Google DeepMind News
L
LINUX DO - 最新话题
T
Tailwind CSS Blog
N
Netflix TechBlog - Medium
Forbes - Security
Forbes - Security
MongoDB | Blog
MongoDB | Blog
Attack and Defense Labs
Attack and Defense Labs
Webroot Blog
Webroot Blog
A
About on SuperTechFans
Schneier on Security
Schneier on Security
Hacker News - Newest:
Hacker News - Newest: "LLM"
Microsoft Azure Blog
Microsoft Azure Blog
F
Fortinet All Blogs
IT之家
IT之家
The Last Watchdog
The Last Watchdog
腾讯CDC
Microsoft Security Blog
Microsoft Security Blog
Project Zero
Project Zero
B
Blog
Recorded Future
Recorded Future
博客园_首页
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
S
SegmentFault 最新的问题
Security Archives - TechRepublic
Security Archives - TechRepublic
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
H
Hacker News: Front Page
T
Threatpost
H
Heimdal Security Blog
Cloudbric
Cloudbric
Google Online Security Blog
Google Online Security Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
V2EX
云风的 BLOG
云风的 BLOG
V
Visual Studio Blog

博客园 - MSFT:waywa 韦恩卑鄙

[UWP]一种利用Behavior 将StateTrigger集中管理的方案 【干货】个人工作文档节选:XAML MVVM 框架易用性细节优化Tips MVVM Sidekick Win8 RT 轻量级MVVM框架开源 对资源加读写锁的容器 intel I7平台Win7 x64 下wpf、silverlight 与aero特效动画缓慢故障排除一则 今天被Prism里面的一段代码雷到了 1080*1920 下看网站很爽 游戏大厅 从基础开始(8)--绕回来细说聊天室(下)垃圾列表 游戏大厅 从基础开始(7)--绕回来细说聊天室(中间偏下)之女仆编年史2 游戏大厅 从基础开始(6)--绕回来细说聊天室(中)之女仆编年史1 - MSFT:waywa 韦恩卑鄙 游戏大厅 从基础开始(5)--绕回来细说聊天室(上) 简单的树遍历枚举器v0.2-挑战一个程序员到底能多懒- 添加广度优先遍历 一时技痒 不用模拟第一印象的构造 通过三个观察得来的规律解决N^2个往返接力问题 游戏大厅 从基础开始(4)-通过L2X用配置文件反射组装程序(VB only) 关于silverlight depencyobject简单的clone silver light 2 客户端的伪DataTable for EF X360吉他英雄4鼓套装 &1 TB硬盘入手 游戏大厅 从基础开始(3.5)——最吸引眼球的部分 客户端与服务器的连接 的实现 游戏大厅 从基础开始(3)——最吸引眼球的部分 客户端与服务器的连接
对不能用using的成对操作,快速扩展IDisposable的方法
MSFT:waywa 韦恩卑鄙 · 2010-12-09 · via 博客园 - MSFT:waywa 韦恩卑鄙

日常操作中有很多需要打开/关闭   加锁/解锁的成对操作

有时候一些操作原生支持  IDisposable
Monitor 可以用Lock(){}   但是ReadWriteLock 就难了。 还有WCF Channel等)。
这种情况就要用  try/catch/finally,很是丑

封装成IDisposable可能很烦,因为多一个对象要多好多文档。

虽然AOP可能解决一些问题, 但是又没办法精确定位  scrope. 
还是 IDisposable +using最爽

所以写了一个缺省实现。

    /// <summary>  

    /// 销毁帮手,生成可以支持using的自定义IDisposable实例
    /// <remarks>感谢网友@doggo对于 +=OnDispose功能的測試,由於不完善這裡決定取消該功能</remarks>

    /// </summary>  

    public struct Disposable : IDisposable
    {


   
        /// <summary>  

        /// 创建销毁帮手实例  

        /// </summary>  

        /// <param name="onCreate">创建时要做的操作</param>  

        /// <param name="onDispose">销毁是要做的操作</param>  

        public Disposable(Action onCreate, Action onDispose)
        {
            OnDispose = onDispose;


            onCreate();

        }



        /// <summary>  

        /// 销毁时要做的操作          
       /// </summary>  

        private Action OnDispose
        {

                get ;set;

             }  

        ////// <summary>  

        ////// 销毁时要做的操作  支持+=/Addhandler附加操作 (撤銷)  

        ////// </summary>  

        //////public event Action OnDispose ;


        #region IDisposable 成员



        void IDisposable.Dispose()
        {

        
            OnDispose();

            OnDispose = null;

        }



        #endregion



    } 

思路是用一个扩展方法,给一个无dispose 能力的对象 建立一个IDisposable的引用。

由于onCreate onDispose是闭包 额外的参数也是非必要的。

这里提供一个简易读写锁的实现。  大家可以参考

    public static class ReaderWriteerLockSlimHelper 
    {
        /// <summary>
        /// 为读写锁创建支持using的IDisposable帮手
        /// </summary>
        /// <param name="instance">读写锁实例</param>
        /// <param name="lockType">加锁类型 读/写</param>
        /// <returns>帮手实例</returns>
        public static IDisposable CreateDisposable(this ReaderWriterLockSlim instance, LockType lockType)
        {
            var kvp = LockDisposeDic[lockType];
            return new Disposable(() => kvp.Key(instance), () => kvp.Value(instance));
        }

        /// <summary>
        /// 读写的不同操作字典
        /// </summary>
        static Dictionary<LockType, KeyValuePair<Action<ReaderWriterLockSlim>, Action<ReaderWriterLockSlim>>> LockDisposeDic = new Dictionary<LockType, KeyValuePair<Action<ReaderWriterLockSlim>, Action<ReaderWriterLockSlim>>>()
        {
            {
                LockType.Read, 
                new KeyValuePair<Action<ReaderWriterLockSlim>,Action<ReaderWriterLockSlim>> 
                    (
                        ins=>ins.EnterReadLock(),
                        ins=>ins.ExitReadLock()
                    ) 
               
            },
            {
                LockType.Write, 
                new KeyValuePair<Action<ReaderWriterLockSlim>,Action<ReaderWriterLockSlim>> 
                    (
                        ins=>ins.EnterWriteLock(),
                        ins=>ins.ExitWriteLock()
                    ) 
               
            }
        };
            
    }

    public enum LockType
    {
        Read,
        Write
    }

实际使用起来就是爽。 这是一个在需要并发访问的队列中 加入对象的方法。

/// <summary>
        /// 加入有序队列。
        /// </summary>
        /// <param name="item">加入的项目</param>
        public void Enqueue(TValue item)
        {
            using (_lock.CreateDisposable(LockType.Write))
            {
                Queue<TValue> enqueueTarget;
                var key=_keySelector(item);
                if (!_items.ContainsKey(key))
                {
                    var sortValue = _sortValueSelector(item);
                    if (!_index.TryGetValue( _sortValueSelector(item) ,out enqueueTarget ))
                    {
                        enqueueTarget = new Queue<TValue>();
                        _index.Add(sortValue, enqueueTarget);
                    }

                    enqueueTarget.Enqueue(item);
                    _items.Add(key, item);
                }
                else
                {
                    throw new InvalidOperationException("this Item already in queue");
                }
            }

        }

个人工作分享。希望能够帮助大家提高工作效率

附: 容易漏调结束行为的实现  和try catch finally 实现  大家比较下

   出异常会死锁的错误成对掉用 

        /// <summary>
        /// 加入有序队列。
        /// </summary>
        /// <param name="item">加入的项目</param>
        public void Enqueue1(TValue item)
        {
            _lock.EnterWriteLock();

    
                Queue<TValue> enqueueTarget;
                var key = _keySelector(item);
                if (!_items.ContainsKey(key))
                {
                    var sortValue = _sortValueSelector(item);
                    if (!_index.TryGetValue(_sortValueSelector(item), out enqueueTarget))
                    {
                        enqueueTarget = new Queue<TValue>();
                        _index.Add(sortValue, enqueueTarget);
                    }

                    enqueueTarget.Enqueue(item);
                    _items.Add(key, item);
                }
                else
                {
                    throw new InvalidOperationException("this Item already in queue");
                }
                _lock.ExitReadLock(); //不但可能中途退出 还可能像这样写错解锁方法


        }

   正确而麻烦的try catch finally

        /// <summary>
        /// 加入有序队列。
        /// </summary>
        /// <param name="item">加入的项目</param>
        public void Enqueue2(TValue item)
        {
            _lock.EnterWriteLock();

            try
            {
                Queue<TValue> enqueueTarget;
                var key = _keySelector(item);
                if (!_items.ContainsKey(key))
                {
                    var sortValue = _sortValueSelector(item);
                    if (!_index.TryGetValue(_sortValueSelector(item), out enqueueTarget))
                    {
                        enqueueTarget = new Queue<TValue>();
                        _index.Add(sortValue, enqueueTarget);
                    }

                    enqueueTarget.Enqueue(item);
                    _items.Add(key, item);
                }
                else
                {
                    throw new InvalidOperationException("this Item already in queue");
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                _lock.ExitWriteLock();
            
            }


        }