发布于 2013-08-19 02:43:36
假设您在一个WebBrowser应用程序中承载了WinFroms,那么您可以使用async/await模式在一个循环中轻松高效地完成这个任务。试试这个:
async Task DoNavigationAsync()
{
TaskCompletionSource<bool> tcsNavigation = null;
TaskCompletionSource<bool> tcsDocument = null;
this.WB.Navigated += (s, e) =>
{
if (tcsNavigation.Task.IsCompleted)
return;
tcsNavigation.SetResult(true);
};
this.WB.DocumentCompleted += (s, e) =>
{
if (this.WB.ReadyState != WebBrowserReadyState.Complete)
return;
if (tcsDocument.Task.IsCompleted)
return;
tcsDocument.SetResult(true);
};
for (var i = 0; i <= 21; i++)
{
tcsNavigation = new TaskCompletionSource<bool>();
tcsDocument = new TaskCompletionSource<bool>();
this.WB.Navigate("http://www.example.com?i=" + i.ToString());
await tcsNavigation.Task;
Debug.Print("Navigated: {0}", this.WB.Document.Url);
// navigation completed, but the document may still be loading
await tcsDocument.Task;
Debug.Print("Loaded: {0}", this.WB.DocumentText);
// the document has been fully loaded, you can access DOM here
}
}现在,理解DoNavigationAsync异步执行是很重要的。下面是如何从Form_Load调用它并处理它的完成:
void Form_Load(object sender, EventArgs e)
{
var task = DoNavigationAsync();
task.ContinueWith((t) =>
{
MessageBox.Show("Navigation done!");
}, TaskScheduler.FromCurrentSynchronizationContext());
}我回答了一个类似的问题,这里。
发布于 2013-08-19 00:11:10
您不必使用另一个void函数。只需像这样使用lambda:
webB.DocumentCompleted += (sender, e) =>
{
// your post-load code goes here
};发布于 2013-08-19 03:45:44
正确的方法是使用事件。
在您的循环中,如何知道导航已经完成?也许你已经脱离了圈套,但只有一半的时间.
另外,等待时循环被称为忙着等待,并且是CPU昂贵。
为了在页面准备就绪时得到通知,同时保持CPU可用于其他功能,请使用@Jashaszun建议的事件:
void YourFunction()
{
//Do stuff...
webB.DocumentCompleted += (sender, e) =>
{
//Code in here will be triggered when navigation is complete and document is ready
};
webB.Navigate(URL);
//Do more stuff...
}https://stackoverflow.com/questions/18303758
复制相似问题