了解 Silverlight 调度程序
我遇到了无效的跨线程访问问题,但经过一些研究,我设法使用调度程序修复了它。
现在在我的应用程序中我有延迟加载的对象。我将使用 WCF 进行异步调用,并像往常一样使用 Dispatcher 来更新我的对象 DataContext,但它不适用于此场景。不过,我确实在此处找到了解决方案。这是我不明白的地方。
在我的 UserControl 中,我有代码来调用对象上的 Toggle 方法。对该方法的调用是在 Dispatcher 中进行的,如下所示。
Dispatcher.BeginInvoke( () => _CurrentPin.ToggleInfoPanel() );
正如我之前提到的,这还不足以让 Silverlight 满意。我必须在我的对象内进行另一个调度程序调用。我的对象不是 UIElement,而是一个处理所有自己的加载/保存的简单类。
打电话解决了问题
Deployment.Current.Dispatcher.BeginInvoke( () => dataContext.Detail = detail );
因此,通过在班级内
。为什么我必须调用调度程序两次才能实现此目的?高层的呼吁还不够吗? UIElement 中的 Deployment.Current.Dispatcher 和 Dispatcher 之间有区别吗?
I had a Invalid Cross Thread access issue, but a little research and I managed to fix it by using the Dispatcher.
Now in my app I have objects with lazy loading. I'd make an Async call using WCF and as usual I use the Dispatcher to update my objects DataContext, however it didn't work for this scenario. I did however find a solution here. Here's what I don't understand.
In my UserControl I have code to call an Toggle method on my object. The call to this method is within a Dispatcher like so.
Dispatcher.BeginInvoke( () => _CurrentPin.ToggleInfoPanel() );
As I mentioned before this was not enough to satisfy Silverlight. I had to make another Dispatcher call within my object. My object is NOT a UIElement, but a simple class that handles all its own loading/saving.
So the problem was fixed by calling
Deployment.Current.Dispatcher.BeginInvoke( () => dataContext.Detail = detail );
within my class.
Why did I have to call the Dispatcher twice to achieve this? Shouldn't a high-level call be enough? Is there a difference between the Deployment.Current.Dispatcher and the Dispatcher in a UIElement?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
理想情况下,存储一个
Dispatcher
实例,您可以在其他地方使用该实例,而无需对其进行线程检查。调用任何单例 .Current 实例实际上可能会导致调用跨线程访问检查。通过首先存储它,您可以避免这种情况以实际获取共享实例。
我使用“SmartDispatcher”,它在线程外调用时使用调度程序,否则仅调用。它解决了此类问题。
帖子:http://www.jeff.wilcox.name/2010/04/ propertychangedbase-crossthread/
代码:
Ideally, store a single instance of
Dispatcher
that you can use elsewhere without having the thread check on it.Calling any singleton .Current instance may in fact cause a cross-thread access check to be invoked. By storing it first, you can avoid this to actually get the shared instance.
I use a "SmartDispatcher" that uses a dispatcher when called off-thread, and just invokes otherwise. It solves this sort of issue.
Post: http://www.jeff.wilcox.name/2010/04/propertychangedbase-crossthread/
Code:
如果您使用 MVVM light 工具包,您可以使用 Extras dll 中 Galasoft.MvvmLight.Threading 命名空间中的 DispatcherHelper 类。它检查访问并使用调度程序的静态属性,类似于 SmartDispatcher。
在您的 App.xaml.cs 启动事件调用中:
然后在您需要使用调度程序的任何地方使用:
If you use the MVVM light toolkit you could use the DispatcherHelper class in the Galasoft.MvvmLight.Threading namespace in the Extras dll. It checks the access and uses a static property for the dispatcher, similar to the SmartDispatcher.
In your App.xaml.cs startup event call:
Then anywhere you need to use a dispatcher use: