概要
(書きかけ)
「非同期処理」の話とからめて、 GUI アプリケーション開発と非同期処理の話。
GUI とディスパッチャー
(書きかけ、清書時は別ページにするかも)
0.5秒固まったら「使いにくい」、3秒固まったら「バグだ」、10秒固まったら「パソコンが壊れた」と言われる。 ↑ 大げさかもしれないけど、かなり真実。 ・メッセージ ループ クリックとかキー ダウンのイベントは一度キューにたまってる(メッセージ ポンプ) ループでキューを見ては GUI の処理してるものがある。 WinForms とか WPF では隠ぺいされてるけども、内部的には、 while (GetMessage(ref msg, null, 0, 0)) { TranslateMessage(ref msg); DispatchMessage(ref msg); } DispatchMessage の内部で、最終的に以下のようなメソッドが呼ばれてる。 private static IntPtr WndProc( IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { if (msg == WM_LBUTTONDOWN) { MessageBox.Show("左クリックされた"); handled = true; } return IntPtr.Zero; } WndProc 内で重たい処理するとフリーズ。 (結局、イベントハンドラーで重たい処理をするとフリーズ) もちろん避けなきゃいけない。 最初に言った通り、0.5秒超えたら(超える可能性あったら)同期処理すべきじゃない。 ・UI スレッド 一方で、グラフィックがらみは、パフォーマンス上の理由からマルチスレッド不可。 UI 要素は作ったスレッドからしかアクセスしちゃダメ。 ということで、 スレッド立てる → 重たい処理をそっちのスレッドでやる → UI スレッドに制御戻す ってやらないとダメ。 UI スレッドに制御戻すために使うのがディスパッチャー(dispatcher: 配送係) 別スレッドから UI スレッドに、「この処理して」っていうメッセージを配送するって意味。