我做了一个小测试
在其它线程里创建一个依赖对象A 并调用控件的dispatcher类将A作为数据源关联到控件属性上,结果总是提示“必须在创建控件的线程上创建数据源”的异常
后来
我试着将依赖对象更改为普通的CLR对象,却可以正常的被其它线程访问到
在此想问一下 为什么?
为了保证 UI 的线程安全性,UI 操作是串行的,也就是说,你不可能实现同时点击两个 BUTTON,代码执行的再快,两次点击操作也是顺序执行的,是有先后顺序的。因此当你从非 UI 线程来访问一个 UI 元素时,由于 UI 元素本身没有实现线程安全,所以就不允许你从其它线程来访问 UI 元素,你只能把你要执行的操作投递到 UI 的消息泵中去,它会按顺序一个一个的执行。
谢谢 你说的这点我明白
问题是 在其它线程里创建依赖对象 却不可以在dispathcer类里关联到UI上,而如果创建的是普通的对象,却可以,这是为什么
@Tann007: 明白的话就好解释了,其实还是那段话,就是你换个角度理解,dispatcher 执行时的线程为 A,而创建依赖对象的线程是 B,如果你从 A 访问 B,是不是就跨线程了?是不是就违反 UI 的线程安全规则了?
@Launcher: 那当创建的是普通对象 就可以从线程A访问到线程B,而如果创建的是依赖对象 就不可以访问到,请赐教
@Tann007: 所以才叫“依赖对象”和“普通对象”。http://msdn.microsoft.com/zh-cn/library/ms752914(v=vs.110).aspx
也就是说“依赖属性”和控件在线程安全性上的要求是一致的,也就是必须从创建“依赖属性”和控件的线程上去访问。
“那当创建的是普通对象 就可以从线程A访问到线程B,而如果创建的是依赖对象 就不可以访问到,请赐教”,你这话反问的没有道理,因为你这里说的是“普通对象”,它和“依赖对象”是有区别的,你别老盯着线程 A,线程 B 的,你得看线程是要访问何种类型的对象。
我基本上把最开始的一段话,换了个角度讲一遍。
@Launcher: 或者说 依赖对象 不可以跨线程访问?
@Tann007: 其实吧,MSDN 都有,估计我口说,你也不信,所以我不得不给你贴一下:
http://msdn.microsoft.com/zh-cn/library/windows/apps/hh700353.aspx
具体看最后一节“DependencyObject 和线程处理”。
希望你看了后能够按照正确的方式写代码。
使用委托就可以跨线程访问了