C#资源字典XamlParseException - 线程安全?

时间:2011-08-11 12:54:38

标签: c# xaml thread-safety resourcedictionary xamlparseexception

我正在使用静态资源字典,它按以下方式初始化:

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

代码在过去几个月里一直运作良好,但在最近几天我开始遇到以下问题:

  

抛出了类型'System.Xaml.XamlParseException'的异常。   在System.Windows.Baml2006.Baml2006Reader.ReadObject(KeyRecord record)   在System.Windows.ResourceDictionary.CreateObject(KeyRecord key)   在System.Windows.ResourceDictionary.RealizeDeferContent(Object key,Object& value,Boolean& canCache)   在System.Windows.ResourceDictionary.GetValueWithoutLock(Object key,Boolean& canCache)   在System.Windows.ResourceDictionary.GetValue(Object key,Boolean& canCache)

除了上述初始化之外,还可以通过访问所需的项目从字典中读取数据:

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

对代码的唯一修改可能与许多同时访问字典的线程有关。同样重要的是要提到相同的代码有时可以完美地工作,有时会引发上述异常(非常不一致)。

我非常感谢有关异常本身或一般问题的任何见解。

1 个答案:

答案 0 :(得分:0)

ResourceDictionary与Dictionary< TKey,TValue>非常不同。当您从ResourceDictionary读取值时,如果它没有给定键的缓存值,它将解析xaml中的值。

ResourceDictionary使用的xaml解析器不是线程安全的。在ReadObject方法(抛出XamlParseException)中,它首先寻找值所在的xaml读取流中的位置。然后它解析该位置的xaml。

如果两个线程同时尝试从ResourceDictionary中获取一个值,则线程A将寻找对象A的位置并开始读取。然后,线程B将流的读取位置移动到对象B的位置,而线程A位于读取对象A的中间。因此,您将获得XamlParseException。