在 VB.Net 中等待变量改变状态的更好方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18316009/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
A better way to wait for a variable to change state in VB.Net
提问by Osprey
I have a loop that goes through a number of values. With every value iterated, a page is loaded in a webbrowser control (with the value passed as a parameter) and when the page is loaded and read, the loop should go to the next value in the list and continue until all values are processed. I need a way to pause the procedure while the website is loading asynchronously and then resume once the page loading/reading process is complete.
我有一个遍历多个值的循环。随着每个值的迭代,一个页面被加载到一个 webbrowser 控件中(值作为参数传递),当页面被加载和读取时,循环应该转到列表中的下一个值并继续,直到处理完所有值。我需要一种方法来在网站异步加载时暂停该过程,然后在页面加载/读取过程完成后恢复。
The way I am doing is by using something like this, where "ReadingInProgress" is a global variable:
我正在做的方法是使用这样的东西,其中“ReadingInProgress”是一个全局变量:
ReadingInProgress = True
wb.Navigate("http://mywebsite.com/mypage.aspx" & c)
While ReadingInProgress
Application.DoEvents()
End While
The "DocumentCompleted" event of the webrowser control set "ReadingInProgress" to false which causes the while loop to exit and resume the procedure. This works, but I realize that it puts a strain on the CPU. Is there a better, less CPU intensive way to do this?
webrowser 控件的“DocumentCompleted”事件将“ReadingInProgress”设置为 false,这会导致 while 循环退出并恢复该过程。这有效,但我意识到它会给 CPU 带来压力。有没有更好的、CPU 密集程度更低的方法来做到这一点?
Thanks!
谢谢!
采纳答案by noseratio
I've recently answered a similar question. The solution is in C#, but you can use Async/Awaitin VB.NET in a very similar way. Using this technique, you would get a natural flow of execution for your code (DocumentCompleteevent is encapsulated as Task).
我最近回答了一个类似的问题。解决方案是在 C# 中,但您可以以非常相似的方式Async/Await在 VB.NET中使用。使用这种技术,您将获得代码的自然执行流程(DocumentComplete事件被封装为Task)。
回答by cHao
One way would be to take whatever is after the loop, and put that in the handler for the control's DocumentCompleteevent.
一种方法是采用循环后的任何内容,并将其放入控件DocumentComplete事件的处理程序中。
Another would be to have this code run in another thread. It'd start the navigation and then wait on a semaphore, EventWaitHandle, or other waitable object that the DocumentCompletehandler sets. Something like this:
另一种方法是让这段代码在另一个线程中运行。它会启动导航,然后等待处理程序设置的信号量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()
Either way, since you're not taking up the UI thread anymore, you don't have to worry about Application.DoEvents().
无论哪种方式,由于您不再占用 UI 线程,因此您不必担心Application.DoEvents().

