我已经成功构建了一个插件机制,可以在单独的 AppDomain 中创建 UI 控件,并将它们显示为主 AppDomain 中表单的一部分。
这些 UI 控件会加载自己的数据,因此当我打开表单时,会创建大约 10 个不同的插件,每个插件都需要加载其数据。
同样,如果我同步执行,这一切都可以正常工作,但我想在每个插件中使用异步/等待模式。我的刷新方法如下所示:
protected async void RefreshData()
{
_data = await LoadAsync(_taskId); <= UI Thread :)
OnDataChanged(); <= Worker Thread :(
}
现在问题就开始了。当我进入此方法时,我位于主 UI 线程上。但是,当等待结束时,我处于工作线程上,因此我在OnDataChanged()
更新控件的方法。
await
默认情况下应该使用SynchronizationContext.Current
为了它的延续,但由于我在另一个应用程序域中,这恰好是 NULL。
所以我的问题是。如何配置await 以在当前线程(即UI 线程)上继续?
我知道我可以获取一个控件并执行 Invoke() 但我也使用 MVVM 模式,这是在视图模型中,所以我无权访问那里的任何控件,并且所有视图模型 -> 视图通信都是通过数据完成的绑定。
我终于弄清楚如何从单独的 AppDomain 中返回 UI 线程,而无需控件的句柄。
由于我的视图模型始终在 UI 线程上实例化,因此我只需获取当前的调度程序:
_dispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher
现在,在我的 RefreshData 方法中,我所要做的就是在等待之后调度我想要执行的操作。
protected async void RefreshData()
{
_data = await LoadAsync(_taskId); <= UI Thread :)
_dispatcher.Invoke(() => OnDataChanged()); <= UI Thread :)
}
当然,可以通过封装调度程序等使其变得更奇特。
这个想法实际上来自于:MVVM 轻型工具包 http://mvvmlight.codeplex.com/
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)