没有的SynchronizationContext当一个又一个的AppDomain呼叫等待 [英] No SynchronizationContext when calling Await in a another AppDomain
问题描述
我已经成功地建立了一个插件机制,在那里我可以在一个单独的AppDomain创建UI控件,并显示它们作为主要的AppDomain表单的一部分。
I have successfully built a plugin mechanism where I can create UI controls in a separate AppDomain and display them as part of a Form in the main AppDomain.
这些UI控件做自己的数据加载,所以当我打开窗体约10个不同的插件得到创建和每次需要加载数据。
These UI controls do their own data loading so when I open a form about 10 different plugins get created and each needs to load its data.
同样地,如果我这样做同步,但我想用异步/的await图案中的每个插件的这一切工作正常。我的刷新方法如下:
Again this all works fine if I do it synchronously but I would like to use the async/await pattern in each plugin. My refresh method looks like this:
protected async void RefreshData()
{
_data = await LoadAsync(_taskId); <= UI Thread :)
OnDataChanged(); <= Worker Thread :(
}
现在从这里开始的问题。当我进入这个方法,我在主UI线程上。但是,当的await结束了我一个工作线程,所以我得到在更新控制 OnDataChanged()
方法的交叉线异常。
Now here starts the problem. When I enter this method I am on the main UI thread. But when the await is over I am on a worker thread so I get a cross thread exception in the OnDataChanged()
method which updates the controls.
等待
默认情况下应使用 SynchronizationContext.Current
其延续,但因为我在其他的AppDomain这恰好是NULL。
await
should by default use the SynchronizationContext.Current
for its continuation but since I am in an other AppDomain this happens to be NULL.
所以我的问题是。如何配置等待继续当前线程,也就是UI线程?
我知道我可以抓住一个控制和做的invoke(),但我也使用MVVM模式,这是在视图模型,所以我没有获得任何有控制和全视图模型 - >查看通信是通过数据绑定完成的。
I know I can grab a control and do Invoke() but I am also using the MVVM pattern and this is in the View Model so I don't have access to any controls there and all View Model -> View communications are done through data bindings.
推荐答案
我终于想通了,如何找回从单独的AppDomain中的UI线程,而无需手柄来控制。
I finally figured out how to get back to the UI-Thread from within a separate AppDomain, without having a handle to a control.
由于我的视图模型总是在UI线程中实例化,我简单的抓取当前调度:
Since my view model is always instantiated on the UI thread, I simply grab the current dispatcher:
_dispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher
现在在我的RefreshData方法都是我所要做的就是派遣我想要的await后要执行的操作。
Now in my RefreshData method all I have to do is dispatch the action I want to perform after the await.
protected async void RefreshData()
{
_data = await LoadAsync(_taskId); <= UI Thread :)
_dispatcher.Invoke(() => OnDataChanged()); <= UI Thread :)
}
当然,这可以更花哨,通过封装调度等。
This can of course be made more fancy, by encapsulating the dispatcher, etc.
这个想法其实来自的: MVVM光工具包
The idea for this actually came from the: MVVM Light Toolkit
这篇关于没有的SynchronizationContext当一个又一个的AppDomain呼叫等待的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!