DOBON.NET DOBON.NETプログラミング掲示板過去ログ

DoEventsについて

  • 題名: DoEventsについて
  • 著者: agloomyroc
  • 日時: 2009/06/18 11:53:57
  • ID: 24783
  • この記事の返信元:
    • (なし)
  • この記事への返信:
  • ツリーを表示
環境/言語:[WindowsXP/VB.NET 2005]
分類:[.NET]

お世話になります。
VB.NET 2005で下記のコードを書きました。

Private Sub Test()
Try
処理1
Catch ex As Exception
End Try

Application.DoEvents()

Try
処理2
Catch ex As Exception
End Try
End Sub

途中のApplication.DoEventsが実行されるたび、
次の処理2に行かずに上の処理1に戻ってしまいます。

別にループの処理はどこにも書いていないですが、
3回くらい処理1に戻ったら、次の処理2にいきます。

どうしてこんなことが起きるのでしょうか?

どなたかご教授をお願いします。
2009/06/18(Thu) 12:27:05 編集(投稿者)

Windows のウィンドウアプリケーションは、メッセージループというものを持っています。
ウィンドウメッセージを受信するたびにそのメッセージに応じた処理を行い、メッセージがこない間はスリープしています。
ウィンドウメッセージの種類は広範で、画面の描画要求、キーボードやマウスの入力、その他諸々、ウィンドウに関することはほぼ全てメッセージを経由して行われます。
.NET の WinForm ではメッセージはできる限り隠蔽されていますが(代わりに Paint イベントや KeyDown イベントが用意されています)、WndProc メソッドをオーバーライドすれば直接メッセージを処理できたりします。
メッセージの処理は逐次的であり、一つのメッセージの処理中は次のメッセージを処理できず、次のメッセージは溜めておいて現在のメッセージの処理を完了させてから次のメッセージの処理に取りかかります。
ですから、一つの重い処理をメッセージ処理中にやらせると、とたんに他の処理ができなくなります。画面が固まったりキーボードの入力が一時的に無視されたり。
.NET の WinForm も、隠蔽されているだけで背後にはメッセージが存在しているので事情は全く変わりません。

Application.DoEvents は、一つのメッセージの処理中に、溜まっているほかの未処理のメッセージを強制的に先に処理するためのメソッドです。
その Test() メソッドがどのイベントから呼び出されているのか分かりませんが、例えば A キーを入力したときに呼び出され、処理1 に 1 秒かかるとして、
A を適当に連打すれば、処理1 後に Application.DoEvents によって次のメッセージであるキーボード入力メッセージへの処理が行われ、再び Test が呼び出されることになります。でまた処理1 後に Application.DoEvents が……ということに。

元々 DoEvents は、マルチスレッド機能を持たない VB6 以前のために用意されたようなメソッドであり、マルチスレッドが自由に使用できる VB7(VB2002) 以降で使用する意義はほとんどありません。
  • 題名: Re[2]: DoEventsについて
  • 著者: agloomyroc
  • 日時: 2009/06/18 16:21:12
  • ID: 24786
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
Hongliangさん、ご回答ありがとうございました。

DoEventsをRefreshメソッドに変えてうまくできました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板