【问题标题】:EnsureCoreWebView2Async not ready even after CoreWebView2InitializationCompleted event即使在 CoreWebView2InitializationCompleted 事件之后,EnsureCoreWebView2Async 也没有准备好
【发布时间】:2021-06-07 13:33:50
【问题描述】:

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

我很惊讶在 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 已经完成了它的初始化。

如果在 InitializeAsync 中的“等待”之后将 Navigate 移至该代码,则该代码有效。我可能不明白“等待”,我认为它会延迟 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 webView2.EnsureCoreWebView2Async(); 移动到Form.Load 并使处理程序async
  • 当您调用async void 方法时,它实际上是“一劳永逸”。它不会await 调用,而是立即继续。

标签: c# winforms webview2


【解决方案1】:

您需要使用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

【讨论】:

  • 谢谢,这很好地完成了将导航移动到 Form1_Load。但是,它没有回答为什么在“initializationComplete”事件处理程序中引发“尚未初始化”异常(当看似初始化应该完成时)。这是 Microsoft 的错误(或至少是命名和文档问题)吗?
  • 在某一时刻,方法是CoreWebView2Ready。公共方法更改为CoreWebView2InitializationCompleted。不久前我发现初始化可能要等到方法返回后才能完成。除了订阅额外的事件处理程序之外,我决定不在这些方法中放置任何代码。
  • 我认为一旦输入了CoreWebView2InitializationCompleted,WebView2 控件就应该可以使用了——而不是在它从方法返回之后。为了获得所需的行为,我移动了我的代码,如上所示。 WebView2 仍在开发中,因此您可以在这里提交您的想法:github.com/MicrosoftEdge/WebView2Feedback/issues
  • 我添加了另一个选项来减少 Form1_Load 中的代码量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-15
  • 1970-01-01
  • 1970-01-01
  • 2018-11-20
  • 2021-04-22
相关资源
最近更新 更多