時間待機2


kkk  2008-08-20 08:36:40  No: 101025

時間待機ですが、VB6.0なのでこちらに変更しました。

いろいろ、試行してるのですが、良いコードの書き方がわかりません。

for i = 0 to 10
 for k = 0 to 10
  str_Adreess = fncGetAddress(k,i) 'アドレス取得
  call wbbrowser.Navigate(str_Adreess)

  ’10秒待機

 next k
next i

この10秒待機をCPU率を上げないで実装したいです。

Document_Complite で  サクサク進むじゃなくて、
10秒待ちたいのです。

ループだと駄目なんですよね
タイマーも使えないし。。。


8月  2008-08-20 15:11:34  No: 101026

下記では如何ですか?

http://hanatyan.sakura.ne.jp/
「逆引きヘルプ一覧表」上から2/3辺りの 
   プログラムの実行を一定時間停止する(API関数使用)


kkk  2008-08-20 17:42:03  No: 101027

他のフォームで作業をしてるので  Sleep  は使えません。


K.J.K.  2008-08-20 17:51:18  No: 101028

バッチやスクリプトとは異なりますので、イベントドリブンにしてください。

Private mi As Long, mk As Long

Private Sub AutoNavigate()
    mi = 0&
    mk = 0&
    Call WebBrowser1.Navigate(fncGetAddress(mk,mi))
    mk = 1&
    Timer1.Interval = 10000
    Timer1.Enabled = True
End Sub

Private Sub Timer1_Timer()
    Call WebBrowser1.Navigate(fncGetAddress(mk,mi))
    mk = mk + 1&
    If 10& < mk Then
        mk = 0&
        mi = mi + 1&
        If 10& < mi Then
            mi = 0&
            Timer1.Enabled = False
        End If
    End If  
End Sub


higadesu  2008-09-01 11:27:58  No: 101029

DoEvents命令を使用すれば、タイマーに処理がわたると思います。

Declare Function SleepEx Lib "kernel32.dll" _
    (ByVal dwMillsecounds As Long, ByVal bAlertable As Long) As Long
for i = 1 to 100
  call SleepEx(100,false)
  DoEvents
next i


紅閃光  URL  2008-09-09 03:03:41  No: 101030

過去ログにいいのがありますのでそれを読んでみてください。
http://madia.world.coocan.jp/cgi-bin/VBBBS/wwwlng.cgi?print+200502/05020047.txt

それはそれとして、
待機ループの中でSleepとDoEventsを繰り返し使うのは適切でないとよく言われます。
そりゃもうMSより信頼できる魔界の仮面弁士さまやK.J.K.さまといったVIPの方々がそういう発言をしているので間違いありません。(ぇ

Sleepの弊害としては待機中にイベントが無視されるということがあります。
たとえば、デスクトップ上の全てのアプリに対して再描画指令が出たときに待機中だったならウィンドウの表示が愉快なことになったりしますよね。

DoEventsの弊害としてはメッセージキューに溜まったものだけ処理してくれればいいのですが、同じイベントが不必要に何度も発生してしまう危険があります。
たとえば、SocketコントロールのDataArrivalイベントでもってデータを読み出している最中にDoEventsを呼ぶと、もうひとつDataArrivalイベントが発生したりするらしいです。
(わたしはやったことがありませんが)
なんにせよDoEventsの使用は必要最小限にしたほうがいいということだね。

ということで、MSが勧めるMsgWaitForMultipleObjects APIを使用して、sleepを使わない(CPU負荷低)かつ必要最小限なDoEvents呼び出しの待機関数 WaitIdolTime を作って見ました。

' 起動時間を取得
Private Declare Function timeGetTime Lib "winmm.dll" () As Long
Private Const MaxTime = 2 ^ 32 - 1

' メッセージ待機
Private Declare Function MsgWaitForMultipleObjects Lib "user32.dll" ( _
    Optional ByVal Count As Long = 0&, Optional ByVal HandlesPointer As Long = 0&, _
    Optional ByVal WaitAll As Long = 0&, Optional ByVal Milliseconds As Long = 0&, _
    Optional ByVal WakeMask As Long = &HFF&) As Long

Public Sub WaitIdolTime(ByVal msec As Long)
    Dim BeginCount  As Long
    Dim NowCount    As Long
    Dim Interval    As Long
    
    If msec <= 0 Then msec = 1
    
    BeginCount = TimeGetTime()    ' 現在カウント
    Interval = msec
    Do
        ' イベント発生か時間経過まで待機
        If MsgWaitForMultipleObjects(, , , Interval) = 0 Then DoEvents

        ' 待機中イベント発生後の残待機時間
        Interval = msec + BeginCount - NowCount
    Loop While (Interval >= 0&)
End Sub

もっとも、このままでは49.7日後と24.9日後にトンでもないことがおきる可能性があるので、(わたしは)このままでは使う気になりません。
ま、それは先ほど挙げた過去ログで解決されていることですが。

と、まぁ、質問タイトルにそのまま答えればこの通りでいいのですが、
K.J.K.さまが
>バッチやスクリプトとは異なりますので、イベントドリブンにしてください。
とおっしゃっているとおり、今回の件ではタイマーイベントにすべきだと思います。

例えば時間待機関数で待つとしたら、質問者の案ではこのような関数になるとします。

Private Sub AutoNavigate2()
    Dim i As Long, k As Long
    for i = 0 to 10
        for k = 0 to 10
            Call WebBrowser.Navigate(fncGetAddress(k,i))
            Call WaitIdolTime(10000)    ' 10秒待機
        next k
    next i
End Sub

これをボタンクリックで呼び出すとしたらこうなります。

Private Sub Command1_Click()
    Call AutoNavigate2()
'    Call AutoNavigate()    ' K.J.K.さまのサンプルを呼び出す場合
End Sub

イベントドリブンでもボタンクリックイベントに書くコードは一緒です。
AutoNavigate2に全てまとまっているか、
AutoNavigateとTimer1_Timerに分割されているかだけの違いになりますね。

それこそタイマーの名前を変えてしまえば、
Private Sub timAutoNavigate_Timer()
と出来るので、違和感は無いと思いますよ。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加