2012-06-22 30 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