即使在 CoreWebView2InitializationCompleted 事件发生后,EnsureCoreWebView2Async 也未准备好

Baf*_*fin 8 c# winforms webview2

根据 Microsoft 在 Windows 窗体中开始使用 webView2(截至 2021 年 3 月 9 日),我得到了以下代码(未设置 webView2.source;从 Form.Designer.cs 中编辑):

    public Form1() {
      InitializeComponent();
      InitializeAsync();
    }

    async void InitializeAsync() {
      Console.WriteLine("InitializeAsync starting");
      await webView2.EnsureCoreWebView2Async(null);
      Console.WriteLine("InitializeAsync done");
    }

    private void Form1_Load(object sender, EventArgs e) {
      Console.WriteLine("Load event");
    }

    private void webView2_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e) {
      Console.WriteLine("CoreWebView2InitializationCompleted event");
      if ((webView2 == null) || (webView2.CoreWebView2 == null))
        Console.WriteLine("not ready");
      webView2.NavigateToString(File.ReadAllText("index.html"));
    }
Run Code Online (Sandbox Code Playgroud)

我很惊讶在 NavigateToString() 处遇到异常:

System.InvalidOperationException
  HResult=0x80131509
  Message=The instance of CoreWebView2 is uninitialized and unable to complete this operation. See InitializeAsync.
  Source=Microsoft.Web.WebView2.WinForms
  StackTrace:
   at Microsoft.Web.WebView2.WinForms.WebView2.VerifyInitializedGuard()
   at Microsoft.Web.WebView2.WinForms.WebView2.NavigateToString(String htmlContent)
   at webview2_base.Form1.webView2_CoreWebView2InitializationCompleted(Object sender, CoreWebView2InitializationCompletedEventArgs e) in E:\Visual Studio 2019\source\repos\explore\webview2_base\Form1.cs:line 37
   at Microsoft.Web.WebView2.WinForms.WebView2.<InitCoreWebView2Async>d__13.MoveNext()
Run Code Online (Sandbox Code Playgroud)

控制台输出为:

InitializeAsync starting
Load event
CoreWebView2InitializationCompleted event
Exception thrown: 'System.InvalidOperationException' in Microsoft.Web.WebView2.WinForms.dll
An exception of type 'System.InvalidOperationException' occurred in Microsoft.Web.WebView2.WinForms.dll but was not handled in user code
The instance of CoreWebView2 is uninitialized and unable to complete this operation. See InitializeAsync.
Run Code Online (Sandbox Code Playgroud)

那是怎么回事?考虑到事件的标签,我本以为 CoreWebView2 会完成其初始化。

如果 Navigate 移至 InitializeAsync 中的“await”之后,该代码将起作用。我可能不理解“等待”,我认为它会延迟 Form 构造函数和 Load 事件的完成,直到 CoreWebView2 完成之后。

我想将 Navigate 放入 Form Load 事件处理程序中(但它在 CoreWebView2 准备好之前触发)。

我是否不明白某些事情,或者这里是否存在与 CoreWebView2 相关的错误,即使在“initializeComplete”事件已触发后也未初始化?

VS2019 16.9,Net 4.7.2,webview2版本91.0.823.0金丝雀

更新(2021-03-19):如果将“webView2.NavigateToString()”替换为“webView2.CoreWebView2.NavigateToString()”,则它可以工作。但考虑到事件名称,似乎两者都应该在此时起作用。

use*_*821 11

你需要使用await InitializeAsync();哪种手段async void InitializeAsync应该是async Task InitializeAsync。由于async不能与构造函数一起使用,因此您必须从Form1_Load.

请尝试以下操作:

using System.Diagnostics;

选项1

public Form1()
{
    InitializeComponent();
}

private async void Form1_Load(object sender, EventArgs e)
{
    webView2.CoreWebView2InitializationCompleted += WebView_CoreWebView2InitializationCompleted;

    Debug.WriteLine("before InitializeAsync");
    await InitializeAsync();
    Debug.WriteLine("after InitializeAsync");

    //webView2.CoreWebView2.Navigate("https://www.microsoft.com");
    //Debug.WriteLine("after Navigate");

    if ((webView2 == null) || (webView2.CoreWebView2 == null))
    {
        Debug.WriteLine("not ready");
    }

    webView2.NavigateToString(System.IO.File.ReadAllText("index.html"));

    Debug.WriteLine("after NavigateToString");
}

private async Task InitializeAsync()
{
    Debug.WriteLine("InitializeAsync");
    await webView2.EnsureCoreWebView2Async(null);
    Debug.WriteLine("WebView2 Runtime version: " + webView2.CoreWebView2.Environment.BrowserVersionString);
}


private void WebView_CoreWebView2InitializationCompleted(object sender, Microsoft.Web.WebView2.Core.CoreWebView2InitializationCompletedEventArgs e)
{
    Debug.WriteLine("WebView_CoreWebView2InitializationCompleted");
}
Run Code Online (Sandbox Code Playgroud)

输出

before InitializeAsync
InitializeAsync
WebView_CoreWebView2InitializationCompleted
WebView2 Runtime version: 89.0.774.48
after InitializeAsync
after NavigateToString
Run Code Online (Sandbox Code Playgroud)

更新- 这是另一个选择

选项 2

public Form1()
{
    InitializeComponent();
}

private async void Form1_Load(object sender, EventArgs e)
{
    webView2.CoreWebView2InitializationCompleted += WebView_CoreWebView2InitializationCompleted;

    Debug.WriteLine("before InitializeAsync");
    await InitializeAsync();
    Debug.WriteLine("after InitializeAsync");

}

private async Task InitializeAsync()
{
    Debug.WriteLine("InitializeAsync");
    await webView2.EnsureCoreWebView2Async(null);
    Debug.WriteLine("WebView2 Runtime version: " + webView2.CoreWebView2.Environment.BrowserVersionString);

    //webView2.CoreWebView2.Navigate("https://www.microsoft.com");
    //Debug.WriteLine("after Navigate");

    if ((webView2 == null) || (webView2.CoreWebView2 == null))
    {
        Debug.WriteLine("not ready");
    }

    webView2.NavigateToString(System.IO.File.ReadAllText("index.html"));

    Debug.WriteLine("after NavigateToString");
}


private void WebView_CoreWebView2InitializationCompleted(object sender, Microsoft.Web.WebView2.Core.CoreWebView2InitializationCompletedEventArgs e)
{
    Debug.WriteLine("WebView_CoreWebView2InitializationCompleted");
}
Run Code Online (Sandbox Code Playgroud)

输出

before InitializeAsync
InitializeAsync
WebView_CoreWebView2InitializationCompleted
WebView2 Runtime version: 89.0.774.48
after NavigateToString
after InitializeAsync
Run Code Online (Sandbox Code Playgroud)

  • @Skyfish 我完全同意。它被夸大了,充满了开发商过度开发的味道。至少我所需要的就是更新更简单、轻量级的“WebBrowser”控件。相反,需要花费数小时/数天的时间来摆弄这个或第三方解决方案。 (2认同)