【发布时间】:2011-11-03 01:10:37
【问题描述】:
我被要求在类线程中制作字典安全。
我的第一个建议是实现一个线程安全的字典,.net 开发者社区已经在这方面进行了研究,但被拒绝了。
代码是这样的:
class Example()
{
Dictionary<string, string> dic1;
Dictionary<string, string> dic2;
public void Example()
{
dic1 = new Dictionary<string,string>(10);
dic2 = new Dictionary<string,string>(10);
}
public string Method1(string param1)
{
if(dic1.ContainsKey(param1))
{
return dic1[param1];
}
if(IsValidParam(param1))
{
dic1.Add(param1, param1);
return param1;
}
try
{
var params = GetValidParams(param1);
if(params.Count > 0)
{
foreach(var param in params)
{
if(!isValirParam(param)
continue;
dic1.Add(param1, param);
if(!dic2.ContainsKey(param1))
{
dic2.Add(param, param1);
}
return param;
}
}
else
{
dic2.Add(param1, param1);
return param1;
}
}
catch(Exception ex)
{
.....
}
return param1;
}
}
这只是对同一方法内的两个字典具有读写访问权限的众多方法之一。
我正在考虑重构并在每个 Add 和 return 中使用“ReaderWriterLockSlim”,但我不知道这是否会使这个线程安全。
您知道如何解决这个问题吗?我愿意接受建议...
提前感谢您的宝贵时间
【问题讨论】:
-
看看ConcurrentDictionary。也许它会满足您的需求。
-
由于对一个字典的操作依赖于另一个字典中的值测试,ConcurrentDictionary 有帮助,但它本身似乎不够。
-
我现在坚持使用框架 3.5,我们要到明年才能继续使用 4.0 =\抱歉更不用提了
-
想象线程 A 执行该方法,而 param1 不在 dic1 中(因此跳过第一次返回)。在做任何其他事情之前,线程 B 运行相同的代码,但 param1 仍然不在 dic1 中。这是您需要解决的问题:两个线程都通过此方法运行,线程 A 比线程 B 稍早一点,因此线程 B 对早期测试中的 param1 的假设在线程 B 进行测试和它作用于测试结果。
-
我同意 Tridus 的回答,尽管如果你的类有很多方法,有些方法会调用其他方法,它可能会变得复杂。将两个字典视为一个事物,识别针对该事物的原子操作(例如 test+read+write 是一个原子操作),并将这些操作包装在一个锁中。一个很好的免费资源:albahari.com/threading
标签: .net multithreading thread-safety dictionary