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 key) 在 System.Windows.ResourceDictionary.RealizeDeferContent(对象键、对象和值、布尔值和 canCache) 在 System.Windows.ResourceDictionary.GetValueWithoutLock(对象键,Boolean& canCache) 在 System.Windows.ResourceDictionary.GetValue(Object key, Boolean& canCache)
除了上述初始化之外,还通过访问所需的项从字典中读取数据:
if (resource.Contains(key))
{
return resource[key];
}
对代码的唯一修改可能与访问字典的许多线程有关同时。还需要指出的是,相同的代码有时可以完美运行,有时会抛出上述异常(非常不一致)。
如果您对异常本身或一般问题有任何见解,我将不胜感激。
I am using static a Resource Dictionary which is initialized the following way:
static ResourceDictionary resource = new ResourceDictionary()
{
Source = new Uri(
"pack://application:,,,/CommonResources;component/ApplicationData.xaml")
};
The code has been working perfectly for the last few months but in the last few days I've started experiencing the following problem:
Exception of type 'System.Xaml.XamlParseException' was thrown.
at System.Windows.Baml2006.Baml2006Reader.ReadObject(KeyRecord record)
at System.Windows.ResourceDictionary.CreateObject(KeyRecord key)
at System.Windows.ResourceDictionary.RealizeDeferContent(Object key, Object& value, Boolean& canCache)
at System.Windows.ResourceDictionary.GetValueWithoutLock(Object key, Boolean& canCache)
at System.Windows.ResourceDictionary.GetValue(Object key, Boolean& canCache)
Aside from the above initialization, the data is read from the dictionary by accessing the needed item:
if (resource.Contains(key))
{
return resource[key];
}
The only modification to the code might be related to many thread accessing the dictionary at the same time. It is also important to mention that the same code sometimes works perfectly and sometimes throws the above exception (Very inconsistent).
I Would appreciate any insights regarding the exception itself or the problem in general.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
ResourceDictionary 与Dictionary有很大不同。当您从 ResourceDictionary 读取值时,如果它没有给定键的缓存值,它将解析 xaml 中的值。
ResourceDictionary 使用的 xaml 解析器不是线程安全的。在 ReadObject 方法中(抛出 XamlParseException 的地方),它首先查找 xaml 读取流中值所在的位置。然后它解析该位置的 xaml。
如果两个线程尝试同时从 ResourceDictionary 中获取值,线程 A 将查找对象 A 的位置并开始读取。然后,线程 B 会将流的读取位置移动到对象 B 的位置,而线程 A 正在读取对象 A。因此您会得到 XamlParseException。
A ResourceDictionary is very different from a Dictionary<TKey,TValue>. When you read a value from a ResourceDictionary, if it doesn't have a cached value for the given key, it will parse the value from the xaml.
The xaml parser used by ResourceDictionary is not thread safe. In the ReadObject method (where the XamlParseException is thrown), it first Seeks to the location in the xaml read stream where the value is located. Then it parses the xaml at that location.
If two threads try and get a value out of a ResourceDictionary at the same time, thread A will seek to the location of the object A and begin reading. Thread B will then move the read position of the stream to the location of object B while thread A is in the middle of reading object A. And so you get a XamlParseException.