ker*_*_xc 5 c# collections thread-safety
我在通过队列枚举时遇到以下异常:
System.InvalidOperationException:集合已被修改; 枚举操作可能无法执行
这是代码摘录:
1: private bool extractWriteActions(out List<WriteChannel> channelWrites)
2: {
3: channelWrites = new List<WriteChannel>();
4: foreach (TpotAction action in tpotActionQueue)
5: {
6: if (action is WriteChannel)
7: {
8: channelWrites.Add((WriteChannel)action);
9: lock(tpotActionQueue)
10: {
11: action.Status = RecordStatus.Batched;
12: }
13: }
14: }
15: return (channelWrites.Count > 0);
16: }
Run Code Online (Sandbox Code Playgroud)
我想我理解了这个问题 - 改变哈希表action.Status = RecordStatus.Batched,这搞砸了枚举器上的MoveNext().问题是,我该如何正确实现"模式"?
我认为我foreach在Collection上使用循环时遇到类似的异常,我试图从Collection中删除项目(或者它可能是List,我不记得了).我最后通过使用for循环来绕过它.也许尝试以下内容:
for (int i=0; i<tpotActionQueue.Count(); i++)
{
TpotAction action = tpotActionQueue.Dequeue();
if (action is WriteChannel)
{
channelWrites.Add((WriteChannel)action);
lock(tpotActionQueue)
{
action.Status = RecordStatus.Batched;
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以更改集合中项目的值.您获得的错误意味着添加或删除了一个项目,即:集合本身已被修改,而不是集合中的项目.这很可能是由另一个线程向此集合添加或删除项目引起的.
您应该在方法的开头锁定队列,以防止其他线程在您访问它时修改集合.或者您可以在调用此方法之前锁定集合.
private bool extractWriteActions(out List<WriteChannel> channelWrites)
{
lock(tpotActionQueue)
{
channelWrites = new List<WriteChannel>();
foreach (TpotAction action in tpotActionQueue)
{
if (action is WriteChannel)
{
channelWrites.Add((WriteChannel)action);
action.Status = RecordStatus.Batched;
}
}
}
return (channelWrites.Count > 0);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
19619 次 |
| 最近记录: |