Ace*_*Ace 8 .net c# concurrency dictionary locking
我正在努力维护.NET项目,我遇到了一些麻烦,我很乐意和你们分享=)
问题代码:
if( evilDict.Count < 1 )
{
foreach (Item item in GetAnotherDict())
if (!evilDict.containsKey(item.name.ToLower().Trim()))
evilDict.add(item.name.ToLower().Trim(), item.ID);
}
Run Code Online (Sandbox Code Playgroud)
尽管contains() - 检查,我收到一个ArgumentException告诉我已经添加了一个具有相同键的项目.我们只是在生产中遇到这个问题,从未进行过测试,这让我怀疑是并发问题.我想知道的是:
这是我的潜在修复,取代了dictionary.add()的东西
protected static void DictAddHelper(Dictionary<String, int> dict, String key, int value)
{
lock (dict)
{
key = key.ToLower().Trim();
if (dict.ContainsKey(key) == false)
{
try
{
dict.Add(key, value);
}
catch (ArgumentException aex)
{
StringBuilder debugInfo = new StringBuilder();
debugInfo.AppendLine("An argumentException has occured: " + aex.Message);
debugInfo.AppendLine("key = " + key);
debugInfo.AppendLine("value = " + value);
debugInfo.AppendLine("---Dictionary contains---");
foreach (String k in dict.Keys)
debugInfo.AppendLine(k + " = " + dict[k]);
log.Error(debugInfo, aex);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:
建议不要求我做一个线程安全的Dict类实现更好,因为这将是一个非常大的重构,不会是一个非常受欢迎的建议=)
EDIT2:
我试过了
lock (((IDictionary)dict).SyncRoot)
Run Code Online (Sandbox Code Playgroud)
但我明白了
Error 28 Using the generic type 'System.Collections.Generic.IDictionary<TKey,TValue>' requires '2' type arguments
Run Code Online (Sandbox Code Playgroud)
然后我试试这个:
lock (((IDictionary<String, int>)dict).SyncRoot)
Run Code Online (Sandbox Code Playgroud)
错误:
Error 28 'System.Collections.Generic.IDictionary<string,int>' does not contain a definition for 'SyncRoot'
Run Code Online (Sandbox Code Playgroud)
最终编辑(我猜):
感谢所有的答案!
现在,我想知道的就是这个.我的方法(DictAddHelper)会不会起作用,如果没有,为什么?
如果您怀疑访问字典时出现并发问题,那么您的修复程序将没有任何用处.它将解决您遇到的特定问题,但是如果您同时访问该字典,将来会遇到更多问题.
在修改字典时,请考虑锁定对字典的访问.
不应该
if (!evilDict.contains(item.name.ToLower().Trim()))
Run Code Online (Sandbox Code Playgroud)
是
if (!evilDict.ContainsKey(item.name.ToLower().Trim()))
Run Code Online (Sandbox Code Playgroud)
?
| 归档时间: |
|
| 查看次数: |
5454 次 |
| 最近记录: |