3

C#リソースディクショナリXamlParseException - スレッドの安全性?私は次のように初期化される静的リソース辞書を使用しています

コードは最後の数ヶ月のために私は次のような問題を経験し始めました、最後の数日間で完璧に取り組んできました
static ResourceDictionary resource = new ResourceDictionary() 
{ 
    Source = new Uri(
     "pack://application:,,,/CommonResources;component/ApplicationData.xaml") 
}; 

タイプ 'System.Xaml.XamlParseException'の例外がスローされました。 System.Windows.ResourceDictionary.RealizeDeferContentでSystem.Windows.ResourceDictionary.CreateObject(KeyRecordキー) でSystem.Windows.Baml2006.Baml2006Reader.ReadObject(KeyRecordレコード) (オブジェクトキー、&値、ブール& canCacheオブジェクト) で System.Windows.ResourceDictionary.GetValueWithoutLock System.Windows.ResourceDictionary.GetValueで(オブジェクトキー、ブール& canCache) (オブジェクトキー、ブール& 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を解析します。

2つのスレッドが同時にResourceDictionaryから値を取得しようとすると、スレッドAはオブジェクトAの場所を探して読み取りを開始します。スレッドAはオブジェクトAの読み込みの途中で、スレッドBはストリームの読み込み位置をオブジェクトBの位置に移動します。これにより、XamlParseExceptionが発生します。

関連する問題