对不能用using的成对操作,快速扩展IDisposable的方法
2010-12-09 11:13
232 查看
日常操作中有很多需要打开/关闭 加锁/解锁的成对操作
有时候一些操作原生支持 IDisposable
Monitor 可以用Lock(){} 但是ReadWriteLock 就难了。 还有WCF Channel等)。
这种情况就要用 try/catch/finally,很是丑
封装成IDisposable可能很烦,因为多一个对象要多好多文档。
虽然AOP可能解决一些问题, 但是又没办法精确定位 scrope.
还是 IDisposable +using最爽
所以写了一个缺省实现。
思路是用一个扩展方法,给一个无dispose 能力的对象 建立一个IDisposable的引用。
由于onCreate onDispose是闭包 额外的参数也是非必要的。
这里提供一个简易读写锁的实现。 大家可以参考
个人工作分享。希望能够帮助大家提高工作效率
附: 容易漏调结束行为的实现 和try catch finally 实现 大家比较下
出异常会死锁的错误成对掉用
有时候一些操作原生支持 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是闭包 额外的参数也是非必要的。
这里提供一个简易读写锁的实现。 大家可以参考
实际使用起来就是爽。 这是一个在需要并发访问的队列中 加入对象的方法。 /// <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 实现 大家比较下
出异常会死锁的错误成对掉用
正确而麻烦的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(); } }
相关文章推荐
- 行级触发器对当前表操作,”ORA-04091: 表 XX 发生了变化, 触发器/函数不能读它“,解决方法
- windos 下 IIS报错: 由于系统缓冲区空间不足或队列已满,不能执行套接字上的操作的解决方法
- C# 001 --- 正确的删除一个控件的事件函数 --- 解决错误: “A”不包含“B”的定义,并且找不到可接受类型为“A”的第一个参数的扩展方法“B”(是否缺少 using 指令或程序集引用?)
- MySQL误操作后快速恢复数据的方法
- 利用反射,泛型,扩展方法快速获取表单值到实体类
- 双系统直接进入grub不能进入ubantu的快速解决方法
- php5.5-win64位下curl扩展不能开启解决方法
- 快速操作(复制、移动)文件的方法
- 解决C#操作PowerShell时有时需要确认的操作不能执行问题,附操作VisualSvn权限的方法
- 方法用于ThinkPHP3.1快速入门连贯操作
- 关于“类不能支持Automation操作”错误的解决方法
- js时间操作扩展方法
- 服务器RAID 硬盘容量扩展 Extend 操作失误的应急方法
- C#利用扩展方法,不引入新的类型,实现矩阵的操作
- 重写——上转型对象不能操作子类新增成员变量和方法但可以操作子类继承和重写的方法
- Ajax 动态载入html页面后不能执行其中的js快速解决方法
- Eclipse对printf()不能输出到控制台的快速解决方法
- fix-ie5.js扩展在IE5下不能使用的几个方法
- 商家QQ在线状态按钮版本太低,不能发起会话,请按如下方法操作
- C#操作操作类库五(字符串的常用扩展方法)