如何从 WebView2 中的 ExecuteScriptAsync 获取同步返回

Ser*_*oos 6 .net winforms async-await webview2

.NET、WinForms。

\n

调用是从 UI 线程触发的(按钮 - 单击)。ExecuteScriptAsync 的返回应继续同步处理,即它们应再次与调用上下文同步。我在这里失败了。

\n

我尝试过例如:

\n
private void buttonTest1_Click(object sender, EventArgs e) {\n        MessageBox.Show(GetMathResult());\n    }\n\n    String GetMathResult() {\n        // a) Application freezes\n        //var result = webView.ExecuteScriptAsync("Math.sin(Math.PI/2)").GetAwaiter().GetResult();\n        //return result;\n\n        // b) return null\n        //String result = null;\n        //Task task = new Task(async () => { result = await webView.ExecuteScriptAsync("Math.sin(Math.PI/2)"); }); \n        //task.RunSynchronously();\n        //return result;\n\n        // 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\xc3\xbchrt werden, da der QueryInterface-Aufruf an die COM - Komponente f\xc3\xbcr die Schnittstelle mit der IID "{4D00C0D1-9434-4EB6-8078-8697A560334F}" aufgrund des folgenden Fehlers nicht durchgef\xc3\xbchrt werden konnte: Schnittstelle nicht unterst\xc3\xbctzt(Ausnahme von HRESULT: 0x80004002(E_NOINTERFACE)).\n        //String result = Task.Run(() => GetMathResultTask()).Result;\n        //return result;\n    }\n\n    Task<String> GetMathResultTask() {\n        return webView.ExecuteScriptAsync("Math.sin(Math.PI/2)");\n    }\n
Run Code Online (Sandbox Code Playgroud)\n

这也不起作用(参见错误):

\n
private void buttonTest3_Click(object sender, EventArgs e) {\n        MessageBox.Show(Y());\n    }\n\n    String Y() {\n        String result = null;\n        var autoResetEvent = new AutoResetEvent(false);\n\n        Task.Run(async () =>\n        {\n            try {\n                result = await webView.ExecuteScriptAsync("Math.sin(Math.PI/2)");\n            }\n            catch (Exception exc) {\n                // !!! {"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\xc3\xbchrt werden, da der QueryInterface-Aufruf an die COM-Komponente f\xc3\xbcr die Schnittstelle mit der IID \\"{4D00C0D1-9434-4EB6-8078-8697A560334F}\\" aufgrund des folgenden Fehlers nicht durchgef\xc3\xbchrt werden konnte: Schnittstelle nicht unterst\xc3\xbctzt (Ausnahme von HRESULT: 0x80004002 (E_NOINTERFACE))."}\n                Console.WriteLine(exc.ToString()); \n            }\n            finally {\n                autoResetEvent.Set();\n            }\n        });\n        autoResetEvent.WaitOne();\n\n        return result;\n    }\n
Run Code Online (Sandbox Code Playgroud)\n

我正在竞标代码示例。

\n

Rez*_*aei 9

ExecuteScriptAsync要从use运算符获取结果await,如下所示:

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);
}
Run Code Online (Sandbox Code Playgroud)

注意:对于那些想要使用 的人WebView2,您需要在计算机上安装WebView2 RuntimeMicrosoft Edge Chromium 。您还需要在项目中安装WebView2 NuGet 包。


Ser*_*oos 5

我可能不得不这样使用它。这是我能找到的最佳解决方案:

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()
        );

    }
Run Code Online (Sandbox Code Playgroud)