I have the following problem.
I am using a simple Windows Runtime Component to communicate between the application and a WebView
. I am doing this according to documentation
This is the code for the Windows Runtime Component
public delegate void NotifyAppHandler( string str );
[AllowForWeb]
public sealed class WebViewInjectionObject
{
public event NotifyAppHandler OnNotifyApp;
public void NotifyApp( string str )
{
OnNotifyApp?.Invoke( str );
}
}
In the OnNavigatedTo
method I initialize the WebViewInjectionObject
and subscribe to the OnNotifyApp
event.
webViewInjectionObject = new WebViewInjectionObject();
webViewInjectionObject.OnNotifyApp += WebViewInjectionObject_OnNotifyApp;
Then on the NavigationStarting
event of the WebView
I call AddWebAllowedObject
on the WebView
private void WebView_NavigationStarting( WebView sender, WebViewNavigationStartingEventArgs args ) {
sender.AddWebAllowedObject( "nativeObject", webViewInjectionObject );
}
The code in the WebViewInjectionObject_OnNotifyApp
method which then interacts with the WebView looks like this.
if (somethingGood) {
await WebView.InvokeScriptAsync( successFunctionName, functionArguments );
}
When running this on the Desktop (Version 1709, Build 16299.371) everything works fine.
When running this on the mobile phone (Version 1709 and Version 1607) I get this exception.
The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))
Usually esceptions like this are solved by using the dspatcher to make the call from the UI thread. I tried doing the followig
await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync( Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
{
await WebView.InvokeScriptAsync( successFunctionName, functionArguments );
} );
But this lead to a deeper exception
A COM call to an ASTA was blocked because the call chain originated in or passed through another ASTA. This call pattern is deadlock-prone and disallowed by apartment call control. A COM call (IID: {638BB2DB-451D-4661-B099-414F34FFB9F1}, method index: 6) to an ASTA (thread 3036) was blocked because the call chain originated in or passed through another ASTA (thread 5964). This call pattern is deadlock-prone and disallowed by apartment call control.
After that I thought of using the SynchronizationContext
so I did this.
In OnNavigatedTo
syncContext = SynchronizationContext.Current;
And then in WebViewInjectionObject_OnNotifyApp
syncContext.Post( async delegate
{
await WBTWebView.InvokeScriptAsync( successFunctionName, functionArguments );
}, null );
This leads again to the first exception.
I am at a loss at what to do next. The goal is to catch the event thrown from the Windows Runtime Component and then call InvokeScriptAsync
on the WebView
in a way that works both for Desktop and Mobile.