3

我使用靜態的資源字典被初始化方式如下:C#資源字典XamlParseException - 線程安全性?

static ResourceDictionary resource = new ResourceDictionary() 
{ 
    Source = new Uri(
     "pack://application:,,,/CommonResources;component/ApplicationData.xaml") 
}; 

的代碼已經在過去的幾個月裏,但在過去的幾天我已經開始遇到了以下問題工作完美:

拋出了'System.Xaml.XamlParseException'類型的異常。 在System.Windows.Baml2006.Baml2006Reader.ReadObject(KeyRecord記錄) 在System.Windows.ResourceDictionary.CreateObject(KeyRecord鍵) 在System.Windows.ResourceDictionary.RealizeDeferContent(對象鍵,對象&值,布爾& canCache) 在System.Windows.ResourceDictionary.GetValueWithoutLock(對象鍵,布爾& canCache) 在System.Windows.ResourceDictionary.GetValue(對象鍵,布爾& canCache)

除了上述初始化時,數據被從讀該字典通過訪問所需的項目:

if (resource.Contains(key)) 
{ 
    return resource[key]; 
} 

對代碼的唯一修改可能與許多線程同時訪問字典有關。同樣重要的一點是,相同的代碼有時可以完美工作,有時會拋出上述異常(非常不一致)。

我希望對異常本身或一般問題的任何見解。

+2

***字典不是線程安全的***不知道爲什麼會導致baml方法拋出,但是您需要鎖定所有多線程字典訪問權限,而不管問題是什麼。 – Will

+0

鎖定確實解決了這個問題,我只是不明白爲什麼讀取字典會導致這樣的異常 – sagibb

+0

啊,這樣的線程錯誤...... – Will

回答

0

ResourceDictionary與字典< TKey,TValue >有很大不同。當您從ResourceDictionary中讀取值時,如果它沒有給定鍵的緩存值,它將解析xaml中的值。

ResourceDictionary使用的xaml解析器不是線程安全的。在ReadObject方法(拋出XamlParseException)中,它首先搜索xaml讀取流中位置值的位置。然後它解析該位置處的xaml。

如果兩個線程同時嘗試從ResourceDictionary中獲取值,則線程A將查找對象A的位置並開始讀取。當線程A位於讀取對象A的中間時,線程B會將流的讀取位置移動到對象B的位置。因此,您將得到一個XamlParseException。