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]; 
} 

코드에 대한 유일한 수정은 사전에 동시에 액세스하는 많은 스레드와 관련 될 수 있습니다. 또한 동일한 코드가 때로는 완벽하게 작동하고 때로는 위의 예외 (매우 일치하지 않음)가 throw된다는 점도 중요합니다.

예외 자체 또는 일반적인 문제에 대한 통찰력을 고맙게 생각합니다.

+2

*** 사전은 스레드로부터 안전하지 않습니다. *** 왜 baml 메서드가 throw되는 지 알 수 없지만 문제가 무엇이든 관계없이 모든 다중 스레드 사전 액세스를 잠글 필요가 있는지 확인하십시오. – Will

+0

잠그면 문제가 해결되었지만 사전에 대한 읽기 액세스가 예외로 throw되는 이유는 알 수 없습니다 – sagibb

+0

아, 이런 스레딩 버그가 있습니다 ... – Will

답변

0

ResourceDictionary는 사전 < TKey, TValue >과 매우 다릅니다. ResourceDictionary에서 값을 읽을 때 지정된 키에 대해 캐시 된 값이 없으면 xaml에서 값을 구문 분석합니다.

ResourceDictionary에서 사용하는 xaml 파서는 스레드로부터 안전하지 않습니다. XamlParseException이 Throw되는 ReadObject 메서드에서 먼저 값이있는 xaml 읽기 스트림의 위치를 ​​찾습니다. 그런 다음 해당 위치의 xaml을 구문 분석합니다.

스레드 두 개가 동시에 ResourceDictionary에서 값을 가져 오면 스레드 A는 개체 A의 위치를 ​​찾고 읽기 시작합니다. 그러면 스레드 B는 스트림 A의 읽기 위치를 객체 B의 위치로 이동시키고 스레드 A는 객체 A를 읽는 중간에있게됩니다. 그러면 XamlParseException이 발생합니다.