Kel*_*lly 21 c# wpf multithreading thread-safety
MSDN说System.Windows.Application的公共静态成员是线程安全的.但是当我尝试使用多个线程运行我的应用程序时,我得到以下异常:
ArgumentException: An entry with the same key already exists.
at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.Collections.Generic.SortedList`2.Add(TKey key, TValue value)
at System.IO.Packaging.Package.AddIfNoPrefixCollisionDetected(ValidatedPartUri partUri,
PackagePart part)
at System.IO.Packaging.Package.GetPartHelper(Uri partUri)
at System.IO.Packaging.Package.GetPart(Uri partUri)
at System.Windows.Application.GetResourceOrContentPart(Uri uri)
at System.Windows.Application.LoadComponent(Uri resourceLocator, Boolean
bSkipJournaledProperties)
at System.Windows.Application.LoadComponent(Uri resourceLocator)
Run Code Online (Sandbox Code Playgroud)
以下调用发生异常:
genericResources = (ResourceDictionary)Application.LoadComponent(new Uri("/Themes/Generic.xaml", UriKind.Relative));
Run Code Online (Sandbox Code Playgroud)
该应用程序在单个线程上工作正常,甚至在两个或三个上.当我从5点起床后,每次都会收到错误.难道我做错了什么?我该怎么做才能解决这个问题?
Ray*_*rns 27
你没有做错事.MSDN错了.Application.LoadComponent实际上不是线程安全的.在我看来,这是WPF中的一个错误.
问题是每当Application.LoadComponent从"Package"加载"Part"时:
您有两个线程调用Application.LoadComponent同时加载相同的部分.MSDN文档说这没关系,但发生的事情是:
该错误的解决方法是将所有对Application.LoadComponent的调用包装在lock()中.
您可以在App.cs或其他地方(您的选择)创建锁定对象:
public static object MyLoadComponentLock = new Object();
Run Code Online (Sandbox Code Playgroud)
然后你的LoadComponent调用如下所示:
lock(App.MyLoadComponentLock)
genericDictionary = (ResourceDictionary)Application.LoadComponent(...
Run Code Online (Sandbox Code Playgroud)