2013-08-19 40 views
1

我有一個循環經歷了一些值。每迭代一個值,就會將一個頁面加載到web瀏覽器控件中(將值作爲參數傳遞),並且在加載並讀取頁面時,循環應轉到列表中的下一個值並繼續,直到處理完所有值。我需要一種方式來暫停過程,同時網站異步加載,然後在頁面加載/讀取過程完成後恢復。一個更好的方式來等待一個變量來改變狀態VB.Net

我做的方法是通過使用這樣的事情,其中​​「ReadingInProgress」是一個全局變量:

 ReadingInProgress = True 
     wb.Navigate("http://mywebsite.com/mypage.aspx" & c) 

     While ReadingInProgress 
     Application.DoEvents() 
     End While 

的「DocumentCompleted」的webrowser控制組「ReadingInProgress」的虛假事件,這導致同時循環退出並恢復程序。這有效,但我意識到它會給CPU帶來壓力。有沒有更好,更少CPU密集的方式來做到這一點?

謝謝!

+0

而不是在循環中等待,爲什麼不把循環後發生的代碼移動到DocumentCompleted事件處理程序呢? –

+0

我不能這樣做,因爲代碼不會在循環後發生,而是在循環內部發生。已經有一些在Web瀏覽器的DocumentCompleted上執行的代碼。我希望循環等待,直到它被執行,然後移動到列表中的下一個項目。換句話說,我需要將.Navigate命令更改爲同步命令。 – Osprey

+0

目前還不清楚爲什麼你不能從'DocumentCompleted'事件處理程序中調用'Navigate'方法。 –

回答

1

我最近回答了similar question。解決方案使用C#,但您可以在VB.NET in a very similar way中使用Async/Await。使用這種技術,您將獲得代碼的自然執行流程(DocumentComplete事件被封裝爲Task)。

+1

根據您提供的鏈接,等待命令已添加到VS2012。不幸的是我使用VS2010。 – Osprey

+0

如果你不能重構你的代碼來使用事件,它必須像你的問題一樣是線性的,至少在'Application.DoEvents()'後面加上'Sleep(200)'。這仍然是一個非常糟糕的模式。至少,你應該禁用UI來緩解代碼重入。 – Noseratio

+0

@Osprey,你的應用程序是否有任何UI窗口?如果是這樣,也許有更好的方法來獲得你想要的,使用模態對話框而不是你的'Application.DoEvents()'循環。 – Noseratio

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

+0

我已經這麼做了。大部分的操作是在DocumentComplete中完成的,它確實設置了一個信號量(while循環等待)。我需要的是一種暫停原始循環(多次調用wb.navigate的循環)的方法,以等待DocumentComplete實際完成,然後再發出另一個web.navigate命令。我需要將wb.navigate轉換爲一個同步命令,它隨着DocumentComplete執行的結束而結束它的執行。 – Osprey

+0

如果'DocumentComplete'設置了信號量,並且您在UI線程外執行此操作,那麼您已經準備好了。對於url中的每個url:wb.navigate(url):sem.WaitOne():(做的):next'。 'sem'當然是'DocumentComplete'處理程序設置的信號量。 – cHao

相關問題