3

.NET、ウィンフォーム。

呼び出しは UI スレッド (ボタン - クリック) からトリガーされます。ExecuteScriptAsync からの戻り値は、引き続き同期的に処理する必要があります。つまり、呼び出しコンテキストと再度同期する必要があります。ここで失敗します。

私は例えば試しました:

private void buttonTest1_Click(object sender, EventArgs e) {
        MessageBox.Show(GetMathResult());
    }

    String GetMathResult() {
        // a) Application freezes
        //var result = webView.ExecuteScriptAsync("Math.sin(Math.PI/2)").GetAwaiter().GetResult();
        //return result;

        // b) return null
        //String result = null;
        //Task task = new Task(async () => { result = await webView.ExecuteScriptAsync("Math.sin(Math.PI/2)"); }); 
        //task.RunSynchronously();
        //return result;

        // c) Excepion: // InvalidCastException: Das COM-Objekt des Typs "System.__ComObject" kann nicht in den Schnittstellentyp "Microsoft.Web.WebView2.Core.Raw.ICoreWebView2Controller" umgewandelt werden. Dieser Vorgang konnte nicht durchgeführt werden, da der QueryInterface-Aufruf an die COM - Komponente für die Schnittstelle mit der IID "{4D00C0D1-9434-4EB6-8078-8697A560334F}" aufgrund des folgenden Fehlers nicht durchgeführt werden konnte: Schnittstelle nicht unterstützt(Ausnahme von HRESULT: 0x80004002(E_NOINTERFACE)).
        //String result = Task.Run(() => GetMathResultTask()).Result;
        //return result;
    }

    Task<String> GetMathResultTask() {
        return webView.ExecuteScriptAsync("Math.sin(Math.PI/2)");
    }

そして、それも機能しません(エラーを参照):

private void buttonTest3_Click(object sender, EventArgs e) {
        MessageBox.Show(Y());
    }

    String Y() {
        String result = null;
        var autoResetEvent = new AutoResetEvent(false);

        Task.Run(async () =>
        {
            try {
                result = await webView.ExecuteScriptAsync("Math.sin(Math.PI/2)");
            }
            catch (Exception exc) {
                // !!! {"Das COM-Objekt des Typs \"System.__ComObject\" kann nicht in den Schnittstellentyp \"Microsoft.Web.WebView2.Core.Raw.ICoreWebView2Controller\" umgewandelt werden. Dieser Vorgang konnte nicht durchgeführt werden, da der QueryInterface-Aufruf an die COM-Komponente für die Schnittstelle mit der IID \"{4D00C0D1-9434-4EB6-8078-8697A560334F}\" aufgrund des folgenden Fehlers nicht durchgeführt werden konnte: Schnittstelle nicht unterstützt (Ausnahme von HRESULT: 0x80004002 (E_NOINTERFACE))."}
                Console.WriteLine(exc.ToString()); 
            }
            finally {
                autoResetEvent.Set();
            }
        });
        autoResetEvent.WaitOne();

        return result;
    }

コードサンプルを入札しています。

4

4 に答える 4

2

ExecuteScriptAsyncuseawait演算子から結果を取得するには、次のようにします。

private async void Form1_Load(object sender, EventArgs e)
{
    await this.webView21.EnsureCoreWebView2Async();
}
private async void button1_Click(object sender, EventArgs e)
{
    var result = await webView21.ExecuteScriptAsync("Math.sin(Math.PI/2)");
    MessageBox.Show(result);
}

注:を使用する場合は、 WebView2 ランタイムMicrosoft Edge ChromiumWebView2がコンピューターにインストールされている必要があります。プロジェクトにWebView2 NuGet パッケージもインストールする必要があります。

于 2020-12-16T18:45:29.647 に答える
1

そういう使い方をすることになりそうです。これは私が見つけることができる最良の解決策です:

private void buttonTest3_Click(object sender, EventArgs e) {
        GetMathResult_v3((x) => {
            MessageBox.Show(x);
            // .. 
        });
    }

    void GetMathResult_v3(Action<String> callbackAction) {

        var task = webView.ExecuteScriptAsync("Math.sin(Math.PI/2)");

        task.ContinueWith(
            (x) => {
                String mathResult = x.Result;
                callbackAction(mathResult);
            }
            , TaskScheduler.FromCurrentSynchronizationContext()
        );

    }
于 2020-12-17T09:47:31.803 に答える