Словарь ресурсов C # XamlParseException - Безопасность потока? - PullRequest
3 голосов
/ 11 августа 2011

Я использую static Resource Dictionary, который инициализируется следующим образом:

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 (ключ объекта, объект и значение, Boolean & canCacheR) в System.Windows.ictionary.GetValueWithoutLock (ключ объекта, Boolean & canCache) в System.Windows.ResourceDictionary.GetValue (ключ объекта, Boolean & canCache)

Помимо вышеуказанной инициализации, данные считываются из словаря путем доступа к необходимойitem:

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

Единственное изменение в коде может быть связано со множеством потоков, одновременно обращающихся к словарю.Также важно упомянуть, что один и тот же код иногда отлично работает, а иногда выдает вышеупомянутое исключение (очень непоследовательное).

Буду признателен за любые идеи относительно самого исключения или проблемы в целом.

1 Ответ

0 голосов
/ 22 февраля 2012

ResourceDictionary очень отличается от словаря,Когда вы читаете значение из ResourceDictionary, если у него нет кэшированного значения для данного ключа, оно будет анализировать значение из xaml.

Анализатор xaml, используемый ResourceDictionary, не является потокобезопасным.В методе ReadObject (где выбрасывается исключение XamlParseException) он сначала ищет местоположение в потоке чтения xaml, в котором находится значение.Затем он анализирует XAML в этом месте.

Если два потока пытаются одновременно получить значение из ResourceDictionary, поток A будет искать местоположение объекта A и начнет чтение.Затем поток B переместит позицию чтения потока в местоположение объекта B, в то время как поток A находится в середине объекта чтения A. И поэтому вы получите исключение XamlParseException.

...