首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Dispatcher.Invoke和Dispatcher.BeginInvoke的线程问题

Dispatcher.Invoke和Dispatcher.BeginInvoke的线程问题
EN

Stack Overflow用户
提问于 2010-12-14 07:23:45
回答 1查看 5.7K关注 0票数 2

根据我的理解,Dispatcher.Invoke和Dispatcher.BeginInvoke在UI线程上执行,唯一的区别是调用是同步的,而BeginInvoke是asynchronous.My问题是当我使用这段代码时。

代码语言:javascript
复制
 EDisc.App.Current.Dispatcher.
              Invoke(
                              DispatcherPriority.Normal, new Action(delegate
                              {
                                  context = NavigationManager.CurrentPage.DataContext;
                              }));

返回上下文的值。但是,使用下面的代码

代码语言:javascript
复制
 EDisc.App.Current.Dispatcher.
              BeginInvoke(
                              DispatcherPriority.Normal, new Action(delegate
                              {
                                  context = NavigationManager.CurrentPage.DataContext;
                              }));

上下文为null,我得到一个InvalidOperation异常,表示“

调用线程无法访问这个对象,因为另一个线程拥有它,我从一个使用UseSynchronizationContext = false .Can执行的WCF服务调用它,有人解释了这种行为吗?

EN

回答 1

Stack Overflow用户

发布于 2010-12-14 11:13:55

BeginInvokeInvoke都将调用一个名为BeginInvokeImpl的内部方法来完成这项工作。不同的是,Invoke在返回之前等待操作完成。

还有一个不同之处:如果您已经在UI线程上,并且正在使用DispatcherPriority.Send,那么Invoke实际上将直接调用该方法,而不通过BeginInvokeImpl调用,这意味着操作是在不经过消息队列的情况下处理的。(如果您不使用Send,那么将首先处理任何其他具有比操作更高属性的消息。)

但是,由于您可能不在这里的UI线程上--您正在进行一些WCF回调--这种特殊情况将不适用。因此,Invoke最终会调用与BeginInvoke相同的底层实现。

从你提供的信息来看,我不得不猜测这里缺少一个细节。您所展示的代码应该可以正常工作,除非您的应用程序中可能有多个UI线程,并且碰巧位于CurrentPage中的页面不时属于不同的线程。

如果您确实有多个UI线程,那么您所使用的方法--通过当前Application对象的dispatcher来推送所有东西--将无法工作,因为您将有多个dispatcher。您需要为您计划接触的任何UI元素获得正确的dispatcher。

顺便说一句,如果您在某个工作线程或回调上构造一个UI对象(例如,Page),您可能会意外地得到多个UI线程。你有可能在什么地方做过这种事吗?

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4436808

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档