2016-12-28 28 views
0

我有以下情況:我有一個C#字典,它有一個int作爲鍵(唯一ID)和一個自定義類作爲值,例如, Dictionary<int, CustomClass>(這不是ConcurrentDictionary)。它是否線程安全/是否有任何競爭條件,如果我產生多個線程,這些線程在整個字典上設置不同類屬性的數據?全部加上在字典上的操作已經在線程設置數據之前完成了。C#併發性:寫在不同的對象屬性

更新的代碼(以明確的事情一點點):

class Foo { 
    public string Prop1 { get; set; } 
    public string Prop2 { get; set; } 
    public string Prop3 { get; set; } 
} 

// Initialized with 100 entries - Keys: 0 to 99 
Dictionary<int, Foo> dict = new Dictionary<int, Foo>(); 

List<Task> tasks = new List<Task>(); 

tasks.Add(Task.Factory.StartNew(() => { 
    for(int i = 0; i < dict.Count; i++) { 
     dict[i].Prop1 = "whatever"; 
    } 
})); 

tasks.Add(Task.Factory.StartNew(() => { 
    for(int i = 0; i < dict.Count; i++) { 
     dict[i].Prop2 = "whatever"; 
    } 
})); 

tasks.Add(Task.Factory.StartNew(() => { 
    for(int i = 0; i < dict.Count; i++) { 
     dict[i].Prop3 = "whatever"; 
    } 
})); 

Task.WaitAll(tasks.ToArray()); 
+1

考慮使用'lock'語句使您的操作線程安全。 – Piou

+0

任何線程是否會訪問該對象的相同對象/值或屬性?這些操作中的任何一個都依賴於讀取屬性值,還是隻設置它們? –

+1

提供有關您計劃如何處理對象的更多細節將會很有幫助。如果您從不同的線程讀取和寫入屬性,可能會出現影響屬性值的競爭條件。最簡單的解決方案是爲每個值設置一個「對象」,在與對象交互時「鎖定」,但這可能是過度殺傷。 –

回答

0

當兩個或兩個以上的代碼訪問相同的資源塊改變其狀態,並且改變其本身和/或這些塊的行爲取決於塊本身的特定執行順序時,就會出現爭用條件。

因此,如果你的線程之間沒有任何關於它們在同一資源上執行的依賴關係,那麼你可以忽略它們是否同時訪問它。

雖然每個人在訪問的屬性上發生「可見」更改並且屬性之間存在某些與其值有關的依賴關係,例如一個屬性在分配時會影響另一個,那麼,你必須同步訪問該屬性。

-2

如果不同的線程中編輯同一個對象的不同屬性,那麼是的,它是安全的。如果您嘗試從多個線程編輯同一對象上的同一屬性,則會出現爭用條件。

這是假設屬性沒有引用共享狀態,這就是您的代碼示例顯示的內容。

+1

不同的屬性仍然可以使用某種共享狀態,所以根據所提供的信息,您實際上並不知道它是安全的。 – Servy

+0

問題顯示的代碼,沒有共享狀態...但無論如何添加一個筆記。不知道downvotes是什麼,無論是人們感到困惑,或者他們只是不知道。 –

+0

您在顯示代碼之前已回答。如果在代碼顯示後你只回答*,那麼情況就不一樣了。 – Servy