如何在 .NET 6.0 的 WebView2 中等待元素超时可见。具体如何访问UI线程

问题描述 投票:0回答:1

在使用 WebView2 的 .NET 6.0 中,我尝试等待一段时间以查看元素是否在 DOM 中可见(本质上是 Selenium WebDriverWait 所做的,但在 WebView2 中)。

我认为这段代码应该做到这一点:

internal async Task<bool> WaitForElementToBeVisible(FormWebView2 formWebView2, string element, int numberOfSecondBeforeTimingOut) 
{
    using CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
    CancellationToken cancellationToken = cancellationTokenSource.Token;

    try 
    {
        await Task.Run(async () => {
                while (true) {
                    cancellationToken.ThrowIfCancellationRequested(); // Stop the task if cancelled in the outer catch
                    string webPage = await formWebView2.webView2.ExecuteScriptAsync("document.documentElement.innerHTML"); // Get the web page using JavaScript
                    string decodedWebPage = System.Text.RegularExpressions.Regex.Unescape(webPage);

                    if (decodedWebPage.Contains(element))
                        break; // Stop checking

                    await Task.Delay(100); // Wait 1/10th of a second before checking again
                }
            }).WaitAsync(TimeSpan.FromSeconds(numberOfSecondBeforeTimingOut));

        // If the task ran to completion, ie the element exists,
        Debug.WriteLine("Element exists");

        return true;
    }
    catch (TimeoutException) 
    { 
        // If the task created in try timed out,
        Debug.WriteLine("Timed out after " + numberOfSecondBeforeTimingOut + " seconds");
        cancellationTokenSource.Cancel(); // Cancel the task
        return false;
    }
}

当我运行它时,出现错误:

System.InvalidOperationException:CoreWebView2 只能从 UI 线程访问。

我无法弄清楚如何在 UI 线程上运行它。 在 UI 线程上创建并启动任务看起来很有帮助,但答案似乎在 .NET 6.0 中不再可用。

非常欢迎提出建议,希望能提供示例代码。

c# .net-6.0 webview2 ui-thread
1个回答
0
投票

这可以使用秒表来检查超时:

     internal async Task<bool> WaitForElementToExist(FormWebView2 formWebView2, string element, int secondToWait) {

        // Load Html document
        string webPage = await formWebView2.webView2.ExecuteScriptAsync("document.documentElement.innerHTML"); // Get the web page using JavaScript
        string decodedWebPage = Regex.Unescape(webPage);
        int numberOfMillisecondsToWait = secondToWait * 1000;
        bool elementExists = false;
        Stopwatch stopwatch = new Stopwatch();// Create new stopwatch
        stopwatch.Start();// Begin timing
        while (stopwatch.ElapsedMilliseconds < numberOfMillisecondsToWait) { // While it has not timed out,
            if (decodedWebPage.Contains(element)) { // If the element is in the DOM,
                elementExists = true;
                break; // Stop checking
            }
            await Task.Delay(100); // Wait 1/10th of a second before checking again

            // Check the web page that currently exists
            webPage = await formWebView2.webView2.ExecuteScriptAsync("document.documentElement.innerHTML"); // Get the web page using JavaScript
            decodedWebPage = Regex.Unescape(webPage);
        }
        stopwatch.Stop(); // Stop the Stopwatch
        return elementExists;
    }
© www.soinside.com 2019 - 2024. All rights reserved.