【发布时间】:2013-02-20 05:02:08
【问题描述】:
最近我在使用通用字典时遇到了以下异常
发生了 InvalidOperationException。一个集合被修改了
我意识到这个错误主要是因为我使用的静态字典的线程安全问题。
一点背景知识:我目前有一个应用程序,它有 3 种与此问题相关的不同方法。
- 方法 A 使用
foreach遍历字典并返回一个值。 - 方法 B 将数据添加到字典中。
- 方法 C 更改字典中键的值。
有时在遍历字典时,还会添加数据,这是导致此问题的原因。我在代码的foreach 部分中不断收到此异常,我在其中迭代字典的内容。为了解决这个问题,我用ConcurrentDictionary 替换了通用字典,下面是我所做的详细信息。
目标:我的主要目标是彻底消除异常
对于方法 B(向字典添加新键)我将 .Add 替换为 TryAdd
对于方法 C(更新字典的值)我没有做任何更改。代码的粗略草图如下:
static public int ChangeContent(int para)
{
foreach (KeyValuePair<string, CustObject> pair in static_container)
{
if (pair.Value.propA != para ) //Pending cancel
{
pair.Value.data_id = prim_id; //I am updating the content
return 0;
}
}
return -2;
}
对于方法 A - 我只是在字典上迭代,这是运行代码停止的地方(在调试模式下),Visual Studio 告诉我这是发生错误的地方。我的代码我使用的是类似于下面的
static public CustObject RetrieveOrderDetails(int para)
{
foreach (KeyValuePair<string, CustObject> pair in static_container)
{
if (pair.Value.cust_id.Equals(symbol))
{
if (pair.Value.OrderStatus != para)
{
return pair.Value; //Found
}
}
}
return null; //Not found
}
这些更改是否会解决我遇到的异常。
编辑:
它在this page 上声明GetEnumerator 方法允许您在写入的同时遍历元素(尽管它可能已过时)。这和使用 foreach 不一样吗?
【问题讨论】:
-
foeach 正是这样做的——调用 GetEnumerator/MoveNext/Current。请显示修改字典内容的第三种方法的代码,您究竟在哪一行得到异常?
-
您还没有尝试过新方法,我说得对吗?
-
@sll 这里有一个答案建议我使用
.ToList()然后遍历结果。我猜它已经被删除了 -
我刚刚取消删除我的答案,你能确认这有帮助吗?
标签: c# concurrency