2012-06-22 31 views
1

这里我有一段代码,显示了我想如何更新字典中的值的示例。 我不认为这是最好的方法,因为我不确定它是线程安全的。使用字典的正确方法

编辑:它只是POC代码,我的意思是获取键复制到数组,然后在Dictionary上做的东西。我不能在这里发布雇主的代码,所以我举了个例子来说明问题。

当我得到钥匙阵列的副本时,我可能会在代码的其他部分使用字典引用,其中可能会添加一些密钥,然后这样的函数将不会更新所有密钥,因为我已经在某些时间点。我应该子类化还是可能包装字典并使用锁进行操作,还是有更简单的方法?

我应该如何以适当的方式更新值?

static void Main(string[] args) 
    { 
    Dictionary<string, int> dic = new Dictionary<string, int>(); 

    dic.Add("Kej1",0); 
    dic.Add("Kej2",1); 
    dic.Add("Kej3", 3); 
    dic.Add("Kej4", 3); 

    String[] arr = new string[dic.Count] ; 
    dic.Keys.CopyTo(arr,0); 

    foreach (var va in arr) 
    { 
     Console.WriteLine(dic[va] + " " + va); 
     dic[va] = 10; 
     Console.WriteLine(dic[va] + " " + va); 
    } 
    Console.ReadKey(); 
    } 
+4

不知道这个例子应该显示什么。你提到了多个线程,但是这个例子没有。试着重新回答你的问题。 – Jon

+0

这看起来像一个控制台应用程序。您的代码中没有多个线程。 – Aphelion

+0

@Jon我已经更新了描述,它只是POC代码,有些想象会变得更加明显,我不能在这里发布“不是我的代码”。 – Mateusz

回答

0

您目前的实施情况很好。你的

Dictionary<string, int> dic = new Dictionary<string, int>(); 

是一个局部变量,它只被你的主线程引用。你不需要担心线程安全。

如果你真的使它线程安全的,那么你就可以锁定该词典是这样的:

static void Main(string[] args) 
{ 
    Dictionary<string, int> dic = new Dictionary<string, int>(); 

    lock(dic) 
    { 
    dic.Add("Kej1",0); 
    dic.Add("Kej2",1); 
    dic.Add("Kej3", 3); 
    dic.Add("Kej4", 3); 

    String[] arr = new string[dic.Count] ; 
    dic.Keys.CopyTo(arr,0); 

    foreach (var va in arr) 
    { 
    Console.WriteLine(dic[va] + " " + va); 
    dic[va] = 10; 
    Console.WriteLine(dic[va] + " " + va); 
    } 
    } 
    Console.ReadKey(); 
} 
+0

这是我的第一个想法,但我想以最好的方式做到这一点,现在看起来像是这样。 – Mateusz

3

如果您想要.NET 4以上版本的线程安全字典,可以使用ConcurrentDictionary

+0

是的,你可以但是这有一些意想不到的行为(你可能不会成功)例如你已经习惯了 - 在大多数情况下,一个普通的带有'lock(dict){...}的字典可以很好地完成这个工作 – Carsten

+0

它会允许我更新字典的值,就像上面的例子,我不能更新值,因为枚举中断而将键复制到数组?我将用并发字典来测试一些。 – Mateusz

0

你只需要担心线程安全的,如果你确实使用多个线程。大多数时候你无法在不知不觉中做到这一点。所以不要担心它,并以任何你想要的方式访问你的字典。

如果您使用任何具有“异步”或“开始”一词的任何内容,您可能需要重新考虑这一点。

+0

我更新了问题,它只是POC代码,我无法在此处发布生产代码... – Mateusz