【问题标题】:C# Resource Dictionary XamlParseException - Thread Safety?C# 资源字典 XamlParseException - 线程安全?
【发布时间】:2011-08-11 12:54:37
【问题描述】:

我正在使用静态资源字典,其初始化方式如下:

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(Object key, Boolean& canCache)

除了上面的初始化,通过访问需要的item从字典中读取数据:

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

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

如果能提供有关异常本身或一般问题的任何见解,我将不胜感激。

【问题讨论】:

  • 字典不是线程安全的。不知道为什么会导致 baml 方法抛出,但您需要锁定所有多线程字典访问,不管是什么问题。
  • 锁定确实解决了这个问题,我只是不明白为什么对字典的读取访问会引发这样的异常
  • 啊,这些是线程错误...

标签: c# xaml thread-safety resourcedictionary xamlparseexception


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 2011-10-20
    • 2011-01-17
    相关资源
    最近更新 更多