我有一个循环,经历了许多值。在迭代每个值的情况下,将页面加载到webbrowser控件中(将值作为参数传递),并且在加载和读取页面时,循环应转到列表中的下一个值并继续,直到处理完所有值。我需要一种方法在网站异步加载时暂停程序,然后在页面加载/读取过程完成后恢复。
我正在做的是使用类似的东西,其中“ReadingInProgress”是一个全局变量:
ReadingInProgress = True
wb.Navigate("http://mywebsite.com/mypage.aspx" & c)
While ReadingInProgress
Application.DoEvents()
End While
webrowser控件的“DocumentCompleted”事件将“ReadingInProgress”设置为false,这会导致while循环退出并恢复该过程。这有效,但我意识到它给CPU带来了压力。有没有更好的,更少CPU密集的方式来做到这一点?
谢谢!
答案 0 :(得分:1)
一种方法是接受循环后的任何内容,并将其放在控件的DocumentComplete
事件的处理程序中。
另一种方法是让这个代码在另一个线程中运行。它会启动导航,然后等待信号量EventWaitHandle
或DocumentComplete
处理程序设置的其他可等对象。像这样:
private sem as Semaphore
private withevents wb as WebBrowser
...
sub DoWork()
for each url as String in urls
' You'll almost certainly need to do this, since this isn't the UI thread
' anymore.
wb.invoke(sub() wb.Navigate(url))
sem.WaitOne()
' wb is done
next
end sub
sub wb_DocumentComplete(sender as obj, args as WebBrowserDocumentCompletedEventArgs) _
handles wb.DocumentCompleted
sem.Release()
end sub
...
dim th as new Thread(addressof me.DoWork)
th.Start()
无论哪种方式,由于您不再使用UI线程,因此您不必担心Application.DoEvents()
。
答案 1 :(得分:1)
我最近回答了similar question。解决方案是在C#中,但您可以在VB.NET in a very similar way中使用Async/Await
。使用这种技术,您将获得代码的自然执行流程(DocumentComplete
事件被封装为Task
)。