【发布时间】:2014-09-19 11:38:06
【问题描述】:
我在使用 Window.Show 显示 WPF 窗口时遇到问题:
System.InvalidOperationException 未处理 消息:WindowsBase.dll 中出现“System.InvalidOperationException”类型的未处理异常 附加信息:调用线程无法访问此对象,因为其他线程拥有它。
很公平 - 解决此问题的标准方法是使用 Dispatcher.Invoke 确保窗口显示在 Dispatcher 线程上。
奇怪的是,据我所知,代码已经在 Dispatcher 线程上运行了。
这段代码触发了异常:
if (Dispatcher.CurrentDispatcher.Thread != Thread.CurrentThread ||
Application.Current.Dispatcher.Thread != Thread.CurrentThread)
{
throw new ApplicationException("Current thread is not Dispatcher");
}
window.Show(); // throws InvalidOperationException
这段代码运行良好:
if (Dispatcher.CurrentDispatcher.Thread != Thread.CurrentThread ||
Application.Current.Dispatcher.Thread != Thread.CurrentThread)
{
throw new ApplicationException("Current thread is not Dispatcher");
}
Dispatcher.CurrentDispatcher.Invoke(window.Show);
按照我的理解,如果当前线程是dispatcher线程,那么调用Dispatcher.Invoke应该相当于直接调用方法。显然这是错误的,但有人可以解释原因吗?
为了使问题复杂化,此代码位于通过 COM 从 VB6 应用程序调用的方法中(是的,我知道)。这会产生什么影响?
【问题讨论】:
-
尝试将 Thread.CurrentThread 与 App.Current.Dispatcher.Thread 进行比较。如果没有看到调用 window.Show() 的完整方法,很难判断您是否在调度程序线程上运行。
-
对于这样的问题,您无法得到有用的答案。无用的方法是this one。
-
我试过 Application.Current.Dispatcher 和 Dispatcher.CurrentDispatcher - 它们是一样的。我已经更新了帖子以消除歧义。
-
@roomaroo,您的第一个代码 sn-p
Dispatcher.Current.Thread != Thread.CurrentThread有问题,因为 WPF 中没有Dispatcher.Current属性。 -
@Noseratio 谢谢 - VS 在我写问题时冻结了,所以我无法复制和粘贴!
标签: c# wpf com dispatcher