No Synchronization Context when calling Await in another AppDomain

I have successfully created a plugin mechanism where I can create user interface controls in a separate AppDomain and display them as part of the form in the main AppDomain.

These user interface elements perform their own data loading, so when I open the form, about 10 different plugins are created, and each of them must load its own 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 update method is as follows:

protected async void RefreshData() { _data = await LoadAsync(_taskId); <= UI Thread :) OnDataChanged(); <= Worker Thread :( } 

Now the problem begins here. When I enter this method, I am in the main user interface thread. But when the wait is over, I'm in the workflow, so I get the cross-thread exception in the OnDataChanged() method, which updates the controls.

await should use SynchronizationContext.Current by default to continue it, but since I enter another AppDomain, this is NULL.

So my question. How can I configure to wait for the continuation of the current thread, i.e. a user interface thread?

I know that I can capture the control and make Invoke (), but I also use the MVVM template and this is in the view model, so I don’t have access to any controls and all View Model β†’ View messages are executed using data bindings.

+3
source share
1 answer

I finally figured out how to return to UI-Thread from a separate AppDomain without having a control handle.

Since my view model is always created in the user interface thread, I just grab the current dispatcher:

 _dispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher 

Now in my RefreshData method, all I have to do is send the action that I want to perform after waiting.

 protected async void RefreshData() { _data = await LoadAsync(_taskId); <= UI Thread :) _dispatcher.Invoke(() => OnDataChanged()); <= UI Thread :) } 

This, of course, can be more attractive by encapsulating the dispatcher, etc.

The idea for this really came from: MVVM Light Toolkit

0
source

All Articles