gpt4 book ai didi

c# - 从没有 DoEvents 的 WebBrowser 控件获取 ReadyState

转载 作者:行者123 更新时间:2023-11-30 15:31:04 25 4
gpt4 key购买 nike

这已在此处和其他站点及其工作中被多次讨论,但我想通过其他方式获得想法:

在使用 navigate 或 post 后获得 ReadyState = Complete,因为它的所有缺点而不使用 DoEvents。

我还要注意,使用 DocumentComplete 事件在这里没有帮助,因为我不会只在一个页面上导航,而是像这样一个接一个地导航。

wb.navigate("www.microsoft.com")
//dont use DoEvents loop here
wb.Document.Body.SetAttribute(textbox1, "login")
//dont use DoEvents loop here
if (wb.documenttext.contais("text"))
//do something

它现在的工作方式是使用 DoEvents。我想知道是否有人有适当的方法来等待浏览器方法的异步调用,然后才继续执行其余的逻辑。只是为了它。

提前致谢。

最佳答案

下面是一个基本的 WinForms 应用程序代码,说明了如何等待 DocumentCompleted异步事件,使用 async/await .它导航到多个页面,一个接一个。一切都在主 UI 线程上进行。

而不是调用 this.webBrowser.Navigate(url) ,它可能会模拟单击表单按钮,以触发 POST 样式的导航。

webBrowser.IsBusy异步循环逻辑是可选的,其目的是(非确定性地)考虑可能在 window.onload 之后发生的页面动态 AJAX 代码事件。

using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WebBrowserApp
{
public partial class MainForm : Form
{
WebBrowser webBrowser;

public MainForm()
{
InitializeComponent();

// create a WebBrowser
this.webBrowser = new WebBrowser();
this.webBrowser.Dock = DockStyle.Fill;
this.Controls.Add(this.webBrowser);

this.Load += MainForm_Load;
}

// Form Load event handler
async void MainForm_Load(object sender, EventArgs e)
{
// cancel the whole operation in 30 sec
var cts = new CancellationTokenSource(30000);

var urls = new String[] {
"http://www.example.com",
"http://www.gnu.org",
"http://www.debian.org" };

await NavigateInLoopAsync(urls, cts.Token);
}

// navigate to each URL in a loop
async Task NavigateInLoopAsync(string[] urls, CancellationToken ct)
{
foreach (var url in urls)
{
ct.ThrowIfCancellationRequested();
var html = await NavigateAsync(ct, () =>
this.webBrowser.Navigate(url));
Debug.Print("url: {0}, html: \n{1}", url, html);
}
}

// asynchronous navigation
async Task<string> NavigateAsync(CancellationToken ct, Action startNavigation)
{
var onloadTcs = new TaskCompletionSource<bool>();
EventHandler onloadEventHandler = null;

WebBrowserDocumentCompletedEventHandler documentCompletedHandler = delegate
{
// DocumentCompleted may be called several time for the same page,
// if the page has frames
if (onloadEventHandler != null)
return;

// so, observe DOM onload event to make sure the document is fully loaded
onloadEventHandler = (s, e) =>
onloadTcs.TrySetResult(true);
this.webBrowser.Document.Window.AttachEventHandler("onload", onloadEventHandler);
};

this.webBrowser.DocumentCompleted += documentCompletedHandler;
try
{
using (ct.Register(() => onloadTcs.TrySetCanceled(), useSynchronizationContext: true))
{
startNavigation();
// wait for DOM onload event, throw if cancelled
await onloadTcs.Task;
}
}
finally
{
this.webBrowser.DocumentCompleted -= documentCompletedHandler;
if (onloadEventHandler != null)
this.webBrowser.Document.Window.DetachEventHandler("onload", onloadEventHandler);
}

// the page has fully loaded by now

// optional: let the page run its dynamic AJAX code,
// we might add another timeout for this loop
do { await Task.Delay(500, ct); }
while (this.webBrowser.IsBusy);

// return the page's HTML content
return this.webBrowser.Document.GetElementsByTagName("html")[0].OuterHtml;
}
}
}

如果您希望通过控制台应用程序执行类似的操作,这里是 an example of that .

关于c# - 从没有 DoEvents 的 WebBrowser 控件获取 ReadyState,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21140349/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com