简体   繁体   中英

No SynchronizationContext when calling Await in a another 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.

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.

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 :( 
}

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.

await should by default use the SynchronizationContext.Current for its continuation but since I am in an other AppDomain this happens to be NULL.

So my question is. How can I configure await to continue on the current thread, that is the UI thread?

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.

I finally figured out how to get back to the UI-Thread from within a separate AppDomain, without having a handle to a control.

Since my view model is always instantiated on the UI thread, I simply grab the current dispatcher:

_dispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher

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.

The idea for this actually came from the: MVVM Light Toolkit

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM