没有的SynchronizationContext当一个又一个的AppDomain呼叫等待 [英] No SynchronizationContext when calling Await in a another AppDomain

查看:183
本文介绍了没有的SynchronizationContext当一个又一个的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆