等待变量在VB.Net中更改状态的更好方法

时间:2013-08-19 14:13:13

标签: vb.net loops webbrowser-control wait

我有一个循环,经历了许多值。在迭代每个值的情况下,将页面加载到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密集的方式来做到这一点?

谢谢!

2 个答案:

答案 0 :(得分:1)

一种方法是接受循环后的任何内容,并将其放在控件的DocumentComplete事件的处理程序中。

另一种方法是让这个代码在另一个线程中运行。它会启动导航,然后等待信号量EventWaitHandleDocumentComplete处理程序设置的其他可等对象。像这样:

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)。