DoEvents
DoEvents っていうと、VB6 時代に使ったなーとか妙に懐かしいです。C とか C++ だとこんな実装をしてました。
void DoEvents (void) { MSG msg; while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage (&msg); DispatchMessage (&msg); } }
要するに、メインのメッセージループの内側で、同期的にメッセージループを実行してメッセージキュー内にたまってるメッセージを捌かせるもので、主に同期処理の合間に GUI が固まらないようにする目的で使うやつです。Borland 系では Application->ProcessMessages () がおんなじ様な実装になってたんだと思います。多分。
WPF では DispatcherFrame クラスがメッセージループを表わすらしく、Dispatcher.PushFrame でそれを実行できます。たまってたメッセージを処理し終えた際にループを終了する必要がありますが、ディスパッチスレッドに優先度の低い処理としてメッセージループの終了を登録しておくことで実現します。
実際の実装方法は MSDN のあちこちにありますが、関数一個にした版をとりあえず上げときます。
/// <summary> /// 現在メッセージ待ち行列の中にある全てのUIメッセージを処理します。 /// </summary> public static void DoEvents () { // うちっかわの DispatcherFrame を作成 var nestedFrame = new DispatcherFrame (); // DispatcherFrame (= 実行ループ) を終了させるコールバック DispatcherOperationCallback callback = (frame) => { ((DispatcherFrame) frame).Continue = false; return null; // 非同期で実行する // 優先度を Background にしているので、このコールバックは // ほかに処理するメッセージがなくなったら実行される var operation = Dispatcher.CurrentDispatcher.BeginInvoke (DispatcherPriority.Background, callback, nestedFra // うちっかわの実行ループを開始する Dispatcher.PushFrame (nestedFrame); // コールバックのオペレーションが完了していない場合、強制終了する if (operation.Status != DispatcherOperationStatus.Completed) { operation.Abort (); } }
トラックバック
- このエントリーにトラックバック:
- http://frog.raindrop.jp/cgi-bin/mt/mt-tb.cgi/2344
コメント