在 .NET 中同步读写集合
我有一个包含项目集合的对象。我希望能够通过 AddItem 方法将项目添加到集合中,并浏览集合中的所有项目。我的对象必须是线程安全的。我正在使用 ReaderWriterLockSlim 来确保正确的同步。 我应该如何同步 GoThroughAllItems 方法?我应该在整个持续时间内启动一个大的 ReadLock(这可能会很长),还是应该释放从集合中获取的每一项的锁,并为下一项重新获取锁?
这是一些示例代码:
private ReaderWriterLockSlim @lock = new ReaderWriterLockSlim(); private List items = new List(); public void AddItem(Item item) { [email protected](); try { //do something with item and add it to the collection this.items.Add(item); } finally { [email protected](); } } public void GoThroughAllItems() { [email protected](); try { foreach (Item item in this.Items) { #if option2 [email protected](); #endif //process item, which may take a long time #if option2 [email protected](); #endif } } #if option2 catch #endif #if option1 finally #endif { [email protected](); } }
I have an object which holds a collection of items. I want to be able to add items to the collection through an AddItem method and also to go through all of the items in the collection. My object must be thread safe. I am using a ReaderWriterLockSlim to assure proper synchronization.
How should I synchronize the GoThroughAllItems method? Should I just start a big ReadLock throughout its entire duration, which may be very long, or should I release the lock for each item fetched from the collection, and re-acquire the lock again for the next one?
Here is some sample code:
private ReaderWriterLockSlim @lock = new ReaderWriterLockSlim(); private List items = new List(); public void AddItem(Item item) { [email protected](); try { //do something with item and add it to the collection this.items.Add(item); } finally { [email protected](); } } public void GoThroughAllItems() { [email protected](); try { foreach (Item item in this.Items) { #if option2 [email protected](); #endif //process item, which may take a long time #if option2 [email protected](); #endif } } #if option2 catch #endif #if option1 finally #endif { [email protected](); } }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这里最好的方法是创建集合的副本,然后对其进行迭代。它有很大的内存开销(但很快就会被释放)。
伪代码:
并且您对每个项目加锁的代码将不起作用,因为其他线程可能会修改集合并会导致错误,因为 foreach 不允许修改集合。
The best way here is to create a copy of collection, then iterate over it. It has significant memory overhead (but it will be released soon after).
Pseudo code:
and you code with locks per item will not work, because other thread might modify collection and it will cause error, because foreach doesn't allow modification of collections.
我会简单地选择第一个选项,即 foreach 周围的读取区域,因为读取块中允许多个线程,因此速度相当慢并不重要。另一方面,独占写入操作相当快。所以这应该是一个很好的解决方案。
I would simply choose your first option with the read region around the foreach since multiple threads are allowed in the read block it does not matter that it is rather slow. The exclusive write operation on the other hand is quite fast. So that should be a good solution.