Accessing UI thread from Windows Runtime Component throws exception only on Mobile

[亡魂溺海] 提交于 2019-12-13 02:56:43

问题


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.

来源:https://stackoverflow.com/questions/50000838/accessing-ui-thread-from-windows-runtime-component-throws-exception-only-on-mobi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!