1

いくつかの値を通過するループがあります。すべての値が繰り返されると、ページが Web ブラウザー コントロールに読み込まれ (値がパラメーターとして渡されます)、ページが読み込まれて読み取られると、ループはリスト内の次の値に移動し、すべての値が処理されるまで続行する必要があります。Web サイトが非同期に読み込まれている間に手順を一時停止し、ページの読み込み/読み取りプロセスが完了したら再開する方法が必要です。

私がやっている方法は、「ReadingInProgress」がグローバル変数である次のようなものを使用することです。

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

      While ReadingInProgress
        Application.DoEvents()
      End While

webbrowser コントロールの "DocumentCompleted" イベントは、"ReadingInProgress" を false に設定します。これにより、while ループが終了し、手順が再開されます。これは機能しますが、CPU に負担がかかることに気付きました。これを行うための、より優れた CPU 集中型の方法はありますか?

ありがとう!

4

2 に答える 2

1

最近、同様の質問に回答しました。ソリューションは C# にありますがAsync/Await、VB.NETでも非常によく似た方法で使用できます。この手法を使用すると、コードの実行の自然なフローが得られます (DocumentCompleteイベントは としてカプセル化されますTask)。

于 2013-08-19T15:25:58.170 に答える
1

DocumentComplete1 つの方法は、ループの後にあるものをすべて取得し、それをコントロールのイベントのハンドラーに入れることです。

もう 1 つの方法は、このコードを別のスレッドで実行することです。ナビゲーションを開始し、ハンドラーが設定するセマフォ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()

于 2013-08-19T14:21:24.240 に答える