在使用 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 中不再可用。
非常欢迎提出建议,希望能提供示例代码。
这可以使用秒表来检查超时:
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;
}