Доступ к потоку пользовательского интерфейса из компонента среды выполнения Windows создает исключение только на мобильном устройстве - PullRequest
0 голосов
/ 24 апреля 2018

У меня следующая проблема.Я использую простой компонент среды выполнения Windows для связи между приложением и WebView.Я делаю это в соответствии с документацией

Это код компонента времени выполнения Windows

 public delegate void NotifyAppHandler( string str );

[AllowForWeb]
public sealed class WebViewInjectionObject
{
    public event NotifyAppHandler OnNotifyApp;

    public void NotifyApp( string str )
    {
        OnNotifyApp?.Invoke( str );
    }
}

В методе OnNavigatedTo я инициализирую WebViewInjectionObject иподписаться на событие OnNotifyApp.

 webViewInjectionObject = new WebViewInjectionObject();
 webViewInjectionObject.OnNotifyApp += WebViewInjectionObject_OnNotifyApp;    

Затем на NavigationStarting событии WebView я вызываю AddWebAllowedObject на WebView

 private void WebView_NavigationStarting( WebView sender, WebViewNavigationStartingEventArgs args ) {
        sender.AddWebAllowedObject( "nativeObject", webViewInjectionObject );
    }

Код в методе WebViewInjectionObject_OnNotifyApp, который затемвзаимодействует с WebView выглядит следующим образом.

if (somethingGood) {
    await WebView.InvokeScriptAsync( successFunctionName, functionArguments ); 
}

При запуске этого на рабочем столе (Версия 1709, сборка 16299.371) все работает нормально.

При запуске этого на мобильном телефоне (Версия 1709 и Версия 1607) я получаю это исключение.

Приложение вызвало интерфейс, который был назначен для другого потока.(Исключение из HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))

Обычно подобные исключения решаются с помощью dspatcher для выполнения вызова из потока пользовательского интерфейса.Я попытался выполнить следующее:

 await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync( Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
      {
           await WebView.InvokeScriptAsync( successFunctionName, functionArguments );
      } );

Но это привело к более глубокому исключению

COM-вызов ASTA был заблокирован, потому что цепочка вызовов возникла или прошла через другую ASTA.Этот образец вызова является склонным к тупику и запрещен контролем вызова квартиры.Вызов COM (IID: {638BB2DB-451D-4661-B099-414F34FFB9F1}, индекс метода: 6) для ASTA (поток 3036) был заблокирован, поскольку цепочка вызовов возникла или прошла через другую ASTA (поток 5964).Этот шаблон вызовов подвержен тупикам и запрещен управлением вызовами в квартирах.

После этого я подумал об использовании SynchronizationContext, поэтому я сделал это.В OnNavigatedTo

syncContext = SynchronizationContext.Current;

А затем в WebViewInjectionObject_OnNotifyApp

 syncContext.Post( async delegate
        {
             await WBTWebView.InvokeScriptAsync( successFunctionName, functionArguments );
        }, null );

Это снова приводит к первому исключению.

Я в растерянности от того, чтоделать дальшеЦель состоит в том, чтобы перехватить событие, генерируемое компонентом среды выполнения Windows, а затем вызвать InvokeScriptAsync на WebView так, чтобы это работало как для настольных компьютеров, так и для мобильных устройств.

...