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

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

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

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

 

所以写了一个缺省实现。

 /// <summary>
    /// 销毁帮手,生成可以支持using的自定义IDisposable实例
    /// </summary>
    public  struct Disposable :IDisposable
    {

        /// <summary>
        /// 创建销毁帮手实例
        /// </summary>
        /// <param name="onCreate">创建时要做的操作</param>
        /// <param name="onDispose">销毁是要做的操作</param>
            public Disposable(Action onCreate, Action onDispose)
            {
                _onDispose = onDispose;
                onCreate();
            }

            private Action _onDispose;
            /// <summary>
            /// 销毁时要做的操作  支持+=/Addhandler附加操作
            /// </summary>
            public Action OnDispose
            {
                get { return _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
}

 

 

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

 

 

public void Enqueue(TValue item)
{
using (_lock.CreateDisposable(LockType.Write))
{
Queue
<TValue> enqueueTarget;
if (!_items.ContainsKey(_keySelector(item)))
{
//blahblah
}
else
{
throw new InvalidOperationException("this Item already in queue");
}
}

}

 

 

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

 

 

 

作者: 韦恩卑鄙 v-zhewg @waynebaby 发表于 2010-12-09 11:13 原文链接

推荐.NET配套的通用数据层ORM框架:CYQ.Data 通用数据层框架