我对此感到非常困惑,这让我开始质疑我对WPF资源系统的整体理解
我有一个多窗口应用程序,其中每个窗口派生的对象都运行在具有单独调度程序的单独线程上。
Thread t = new Thread(() => {
Window1 win = new Window1();
win.Show();
System.Windows.Threading.Dispatcher.Run();
});
t.SetApartmentState(ApartmentState.STA);
t.Start();我有一个Dictionary1.xaml资源字典,里面有一个命名样式对象(它只是将Background属性设置为Red,并以TextBox为目标)。在我的App.xaml中,我通过ResourceDictionary.MergedDictionaries集合引用Dictionary1.xaml。在我的其他窗口的XAML中,我有一个指向textbox控件中Style键的StaticResource,它可以工作。
我可以打开多个窗口,但是我不应该得到交叉线程错误吗?在其中一个窗口类的构造函数中,我这样做了:
Style s = (Style)TryFindResource("TestKey");
Console.WriteLine(((Setter)s.Setters[0]).Property.Name); // no problem
s.Dispatcher == this.Dispatcher // false既然样式对象是从DispatcherObject派生的,这是否意味着只有拥有它的线程才能访问它?如果一个对象是在ResourceDictionary中定义的,这是否意味着在默认情况下,它是一个静态实例?这是如何工作的呢?为什么我没有得到一个跨线程的错误?
(我错误地报告了一个问题,因为我删除了一个由其他原因引起的交叉线程错误)
我对此感到非常困惑--我以为只有冻结的可冻结对象才能在线程间共享。为什么允许我访问其他线程上的DispatcherObject?
发布于 2012-11-20 17:17:19
我对你的“问题”也很困惑。dispatcher对象没有什么神奇之处,线程亲和性应该在继承自DispatcherObject的类中编码:每个不应该兼容多线程的访问器都应该调用DispatcherObject提供的base.VerifyAccess()方法。下面是定义Style.Setters属性的getter的方式:
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public SetterBaseCollection Setters
{
get
{
base.VerifyAccess();
if (this._setters == null)
{
this._setters = new SetterBaseCollection();
if (this._sealed)
{
this._setters.Seal();
}
}
return this._setters;
}
}因此,在您的情况下,确实应该抛出一个异常...
也许您可以尝试调用s.CheckAccess()方法。您还可以尝试使用dispatcher比较Object.ReferenceEquals(A,B)方法来确保equal操作符没有被重载(尽管我没有发现任何重载...)。
这个主题非常有趣,请随时与我们联系!
https://stackoverflow.com/questions/13468103
复制相似问题