c# – 同步的IEnumerator
发布时间:2020-12-16 01:35:29 所属栏目:百科 来源:网络整理
导读:我正在整理一个自定义的SynchronizedCollection T class,以便我可以为我的 WPF应用程序提供一个同步的Observable集合.同步是通过ReaderWriterLockSlim提供的,在大多数情况下,它很容易应用.我遇到问题的情况是如何提供集合的线程安全枚举.我创建了一个自定义I
我正在整理一个自定义的SynchronizedCollection< T> class,以便我可以为我的
WPF应用程序提供一个同步的Observable集合.同步是通过ReaderWriterLockSlim提供的,在大多数情况下,它很容易应用.我遇到问题的情况是如何提供集合的线程安全枚举.我创建了一个自定义IEnumerator< T>嵌套类看起来像这样:
private class SynchronizedEnumerator : IEnumerator<T> { private SynchronizedCollection<T> _collection; private int _currentIndex; internal SynchronizedEnumerator(SynchronizedCollection<T> collection) { _collection = collection; _collection._lock.EnterReadLock(); _currentIndex = -1; } #region IEnumerator<T> Members public T Current { get; private set;} #endregion #region IDisposable Members public void Dispose() { var collection = _collection; if (collection != null) collection._lock.ExitReadLock(); _collection = null; } #endregion #region IEnumerator Members object System.Collections.IEnumerator.Current { get { return Current; } } public bool MoveNext() { var collection = _collection; if (collection == null) throw new ObjectDisposedException("SynchronizedEnumerator"); _currentIndex++; if (_currentIndex >= collection.Count) { Current = default(T); return false; } Current = collection[_currentIndex]; return true; } public void Reset() { if (_collection == null) throw new ObjectDisposedException("SynchronizedEnumerator"); _currentIndex = -1; Current = default(T); } #endregion } 但是,我担心的是,如果Enumerator没有Disposed,那么锁永远不会被释放.在大多数用例中,这不是问题,因为foreach应该正确调用Dispose.但是,如果使用者检索显式的Enumerator实例,则可能会出现问题.我唯一的选择是使用一个警告实现者来记录该类,提醒消费者在明确使用Enumerator时调用Dispose,或者有没有办法在最终确定期间安全地释放锁定?我想不是,因为终结器甚至没有在同一个线程上运行,但我很好奇是否还有其他方法来改进它. 编辑 在考虑了这一点并阅读了回复之后(特别感谢Hans),我认为这绝对是一个坏主意.实际上,最大的问题不是忘记Dispose,而是一个悠闲的消费者在枚举时创造僵局.我现在只读取锁定足够长的时间来获取副本并返回副本的枚举器. 解决方法
你是对的,这是一个问题.终结器是没用的,它运行得太晚,无法使用.无论如何,代码应该在此之前严重陷入僵局.不幸的是,您无法区分调用MoveNext / Current成员的foreach或显式使用它们的客户端代码.
没有修复,不要这样做.微软也没有这样做,他们有充分的理由支持.NET 1.x.您可以创建的唯一真正的线程安全迭代器是在GetEnumerator()方法中创建集合对象的副本的迭代器.迭代器与集合不同步也不是快乐. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- postgresql – AWS Redshift JDBC插入性能
- 正则表达式:反向引用
- Oracle解锁表被锁
- 正则表达式 – 从Perl中的字符串中删除文件扩展名和路径
- 如何解决源和目标库SCN同步问题
- Cocos2d-X中使用CCHttpClient实现网络通信
- ruby-on-rails – 如何处理ActiveSupport :: JSON和JSON ge
- nosql – 使用增量计数器在Couchbase群集中生成唯一密钥
- cocos2d-x visual studio warning C4005: “__on_failure”
- [Swift]LeetCode378. 有序矩阵中第K小的元素 | Kth Smalles