当我在此处填写ConcurrentDictionary时,是否有必要使用锁定(lockObj){}块?尽管我怀疑这个场景问题与任何多线程应用程序都有关系,但是在MVC应用程序中会使用它。使用C#中的数据库值填充ConcurrentDictionary的锁定注意事项
在搜索stackoverflow我没有找到这个确切的情况。在第一次从GetOptionById值请求值时,它可以被两个单独的线程调用。
1)难道被认为是更好的做法,使对象列表值,可以在ConcurrentDictionary数据库之前多次没有要求的希望锁定周围充满私人静态的?
2)(即上面的#1)甚至是必要的,还是ConcurrentDictionary能够聪明地完成它自己的工作?预先感谢您的任何意见。
public class MyOptions
{
static string GetOptionById(int id)
{
if (options == null || options.Count <= 0)
FillOptionList();
return options[id];
}
static void FillOptionList()
{
List<MyBusinessObject> objects = DataAccessLayer.GetList();
foreach (MyBusinessObject obj in objects)
options.TryAdd(obj.Id, obj.Name);
}
private static ConcurrentDictionary<int, string> options = new ConcurrentDictionary<int, string>();
}
编辑:谢谢大家的意见,这会是一个更安全的方法吗?
public static string OptionById(int id)
{
if (!options.ContainsKey(id))
{
//perhaps this is a new option and we need to reload the list
FillOptionsOrReturn(true /*force the fill*/);
return (!options.ContainsKey(id)) ? "Option not found" : options[id];
}
else
return options[id];
}
private static void FillOptionsOrReturn(bool forceFill = false)
{
List<MyBusinessClass> objectsFromDb = null;
lock (lockObj)
{
if (forceFill || options == null || options.Keys.Count <= 0)
reasons = DataAccessLayer.GetList();
}
if (objectsFromDb != null)
{
foreach (MyBusinessClass myObj in objectsFromDb)
options.TryAdd(myObj.id, myObj.name);
}
}
private static ConcurrentDictionary<int, string> options = new ConcurrentDictionary<int, string>();
private static object lockObj = new object();
伟大的输入,很可能是字典需要更新,但不经常(也许每天一次),在这种情况下,将使我从数据库中填充的惰性对象集合私有和静态到我的类将是最好的方法? –
likestoski
2012-03-23 17:51:45
@ likestoski:使用'懒惰'仍然是值得的,如果你需要更新字典,那么保持它作为一个ConcurrentDictionary是一个很好的计划。我不确定你的下一部分是什么意思 - 除非你打算阻止*更新*同时发生(是什么触发它们?),我不认为有什么特别的需要。 –
2012-03-23 17:58:49