collections被修改; 枚举操作可能无法执行。 锁在哪里可用?
这是一个只有我正在编写和使用的小程序。
现在我要编写所有使用导致此问题的hashset的区域的代码
我不明白这是怎么可能的。 此项目仅在MainWindow中使用
hsProxyList是一个哈希集
HashSet hsProxyList = new HashSet();
错误发生在下面的迭代中
lock (hsProxyList) { int irRandomProxyNumber = GenerateRandomValue.GenerateRandomValueMin(hsProxyList.Count, 0); int irLocalCounter = 0; foreach (var vrProxy in hsProxyList) { if (irLocalCounter == irRandomProxyNumber) { srSelectedProxy = vrProxy; break; } irLocalCounter++; } } }
我使用hsProxyList的其他地方
我在计算时没有锁定对象 – 我想这不会导致任何错误,但可能不正确 – 不重要
lblProxyCount.Content = "remaining proxy count: " + hsProxyList.Count;
新
lock (hsProxyList) { hsProxyList.Remove(srSelectedProxy); }
新
lock (hsProxyList) { hsProxyList = new HashSet(); foreach (var vrLine in File.ReadLines(cmbBoxSelectProxy.SelectedItem.ToString())) { hsProxyList.Add(vrLine); } }
可以看出我到处都在使用锁。 这是一个multithreading软件。 所有hsProxyList都在MainWindow.xaml.cs中使用 – 它是一个C#WPF应用程序
问题出在你所拥有的地方
lock (hsProxyList) { hsProxyList = new HashSet(); // etc }
所有锁都在特定对象上,但是当您执行hsProxyList = new HashSet
时,您正在更改对象hsProxyList = new HashSet
所以变量hsProxyList引用的对象不再被锁定。
这里有两个问题。 第一个,已经指出的是你在锁定哈希集的同时也将对象hsProxyList
指向更改为:
lock (hsProxyList) { hsProxyList = new HashSet(); // hsProxyList is no longer locked. }
第二个(也是更微妙的)问题是,你假设Count
不需要锁定。 这不是一个安全的假设。 首先,您不知道HashSet
如何实现它。 Count是O(1)
操作的事实表明存在跟踪计数的成员变量。 这意味着在Add
或Remove
必须更新此变量。 Add
的实现可能类似于:
bool Add( T item ) { this.count++; // Point A. addItemToHashSet(item); }
请注意, count
变量会增加, 然后添加项目。 如果调用Add
的线程在A点被中断并且你的另一个调用Count
线程被执行,你将收到一个高于实际元素count
( count
已经递增,但addItemToHashSet
没有)。
这可能没有任何严重的后果,但如果你迭代Count
元素,它可能会导致崩溃。 调用Remove
时也可能出现类似的行为。
上述就是C#学习教程:collections被修改; 枚举操作可能无法执行。 锁在哪里可用?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1006947.html