EnsureCoreWebView2Async 即使在 CoreWebView2InitializationCompleted 事件之后也没有准备好

EnsureCoreWebView2Async not ready even after CoreWebView2InitializationCompleted event

根据微软在 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"));
    }

我很惊讶在 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()

控制台输出为:

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.

这是怎么回事?给定事件标签,我本以为 CoreWebView2 会完成初始化。

如果 Navigate 移动到 InitializeAsync 中的 'await' 之后,则代码有效。我可能不明白'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()' 有效。但是考虑到事件名称,似乎两者都应该在那个时候起作用。

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

调用 InitializeAsync

尝试以下操作:

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");
}

输出:

before InitializeAsync
InitializeAsync
WebView_CoreWebView2InitializationCompleted
WebView2 Runtime version: 89.0.774.48
after InitializeAsync
after NavigateToString

更新 - 这是另一个选项

选项 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");
}

输出:

before InitializeAsync
InitializeAsync
WebView_CoreWebView2InitializationCompleted
WebView2 Runtime version: 89.0.774.48
after NavigateToString
after InitializeAsync