SlideShare a Scribd company logo
.NETラボ 勉強会 2021年9月
オンラインは反応見れないし
スピーカーさんもその場で拾ってもらえなくて
お互いさみしいので、久しぶりに MISAO を動かしてます。
Twitter で #dotnetlab を付けた
発言を拾って画面に表示してます。
一杯書き込んでくれると嬉しいし楽しいです。
画面に出るまで少しタイムラグがあるのでご了承ください。
始める前に…
.NETラボ 勉強会 2021年9月
Windowsにおける
UIスレッドの基礎
とっちゃん(高萩 俊行)
Microsoft MVP for Developer Technologies
since 2005
https://github.com/Tocchann/dotnetlab202109
.NETラボ 勉強会 2021年9月
• ハンドル
– とっちゃん
• 主な活動場所
– わんくま同盟掲示板
– MSDNフォーラム
– わんくま同盟勉強会(休止中)
• お仕事
– ISV
• パッケージソフトの開発
• 良くも悪くも昭和のソフトハウ
ス
– 一応会社員
• Microsoft MVP 歴
– 2005-2008
• Windows – SDK
– 2008-2016
• Visual C++
– 2016-2018
• Visual Studio and Development
Technologies
– 2018-2022
• Developer Technologies
軽く自己紹介
.NETラボ 勉強会 2021年9月
Windowsにおける
UIスレッドの基礎
とっちゃん(高萩 俊行)
Microsoft MVP for Developer Technologies
since 2005
https://github.com/Tocchann/dotnetlab202109
.NETラボ 勉強会 2021年9月
• 本日のゴール
• おことわり
• UIスレッドとは
• まとめ
もくじ
.NETラボ 勉強会 2021年9月
本日のゴール
何をもって
UIスレッド
というかを知る
.NETラボ 勉強会 2021年9月
• 本日のゴール
• おことわり
• UIスレッドとは
• まとめ
もくじ
.NETラボ 勉強会 2021年9月
• 基本的に詳しい解説はなし
– API、メッセージ、プロシージャとかでてくるけど気にしない
• Windows の GUIアプリの話
– コンソールアプリは少し状況が異なる
– NTサービスはだいぶ状況が異なる
• Native Windows 環境での話
– .NET 環境のUIスレッドも基本的に同じ
– 同じOSの上で直接動くアプリ同士なので内部的には大差ない
おことわり
.NETラボ 勉強会 2021年9月
• 現Win32環境が前提
– 現状の動作は正しいものとして扱う
• 動作確認は以下の環境
– Windows 11 21H1
– Surface Book 2
• i7-8650U
• Mem16G/SSD 1T
• Windows は、搭載メモリなどで動作が変わる
– Windows 8 からの挙動
おことわり
.NETラボ 勉強会 2021年9月
• 本日のゴール
• おことわり
• UIスレッドとは
• まとめ
もくじ
.NETラボ 勉強会 2021年9月
• スレッドの種類
• UIスレッドとは
UIスレッドとは
.NETラボ 勉強会 2021年9月
• スレッドには2種類の分類がある
– メインスレッドとそれ以外のスレッド
– UIスレッドとそれ以外のスレッド
スレッドの種類
.NETラボ 勉強会 2021年9月
• メインスレッド
– プロセス作成時に作られるスレッド
– プロセスに一つだけ存在
– メインスレッドが終了するとそのプロセスは破棄される
• サブスレッド
– メインスレッド以外のスレッドの総称
– サブスレッドが動いていていてもプロセスは終了できる
スレッドの種類
.NETラボ 勉強会 2021年9月
• シングルスレッド
– メインスレッドのみのプログラム
• システムが内部処理用に作るスレッドを除く
• マルチスレッド
– メインスレッド以外のスレッドがあるプログラム
• CreateThread, std::thread, std::async
• System.Threading.Tasks.Task
スレッドの種類
.NETラボ 勉強会 2021年9月
• UIスレッド
– プロセスに0個以上存在
– Windowsのメッセージを処理するスレッド
– アパートメントスレッドと呼ばれることもある
– メインスレッドである必要はない
• ワーカースレッド
– UIスレッド以外のすべてのスレッド
– 非UIスレッドと呼ばれることもある
• もしかして、UIスレッドってなくてもいい?
スレッドの種類
.NETラボ 勉強会 2021年9月
• UIスレッドがないと?
– WaitForInputIdle がタイムアウトまで帰ってこない
• リファレンスより
– Waits until the specified process has finished processing its
initial input and is waiting for user input with no input pending,
or until the time-out interval has elapsed.
• 実際のところ…
– プロセスでメッセージを取得(待機)するかタイムアウトまで待
機
• 一般的なアプリではメッセージループに到達するまでに相当
UIスレッドとは-ないとどうなるの?
.NETラボ 勉強会 2021年9月
DEMO
WaitForInputIdle を確認してみる
.NETラボ 勉強会 2021年9月
1. コンソールアプリを待機する場合
2. UIスレッドのないアプリを待機する場合
– .NET 5 ランタイムインストーラ
• WiX 3.14 で作成
– DLL Injection 対応でマルチプロセス構造
– サブプロセスの待機が WaitForSingleObject
» UIスレッドではないメインスレッドのみのプロセス
• シンプルなGUIアプリで確認
3. ウィンドウを作ってから1秒待機
4. ウィンドウ作成前に PeekMessage する場合
5. ウィンドウ作成前に MsgWaitForMultipleObjectする場合
WaitForInputIdle の確認
.NETラボ 勉強会 2021年9月
• スレッドの種類
• UIスレッドとは
UIスレッドとは
.NETラボ 勉強会 2021年9月
• UIスレッド
– 一般にメッセージループを持つスレッドと言われる
– 主にウィンドウメッセージ(HWNDあてメッセージ)を処理
– 他のスレッドやシステムと協調的に動くための根幹を形成する
UIスレッドとは
.NETラボ 勉強会 2021年9月
• メッセージループとは?
– メッセージを処理するループの総称
1. メッセージキューからメッセージを取得
2. メッセージを消化
– 宛先ウィンドウのウィンドウプロシージャにメッセージを送る
– スレッド宛てメッセージを処理
3. 繰り返し不要になるまで1,2を繰り返す
– 通常 WM_QUIT を取得するまで
UIスレッドとは-メッセージループとは
.NETラボ 勉強会 2021年9月
• 最小のメッセージループ
UIスレッドとは-メッセージループとは
// 最小のメッセージループ
int MinimumMessageLoop()
{
MSG msg;
// メッセージキューからメッセージを取得
while( GetMessage( &msg, nullptr, 0, 0 ) )
{
// (お呪い)入力メッセージを変換
TranslateMessage( &msg );
// msg.hWnd のプロシージャにメッセージを処理させる
DispatchMessage( &msg );
}
return static_cast<int>(msg.wParam);
}
.NETラボ 勉強会 2021年9月
• メッセージポンプ
– メッセージの取得と処理部分を切り出した部分処理
– PeekMessageでメッセージを取得して、メッセージを消化
– 空になるまで繰り返すことが多い
• System.Windows.Forms.Application.DoEvents() など
– C++では原則自前実装
• MFC には AfxPumpMessage という1回だけポンプする関数がある
UIスレッドとは
.NETラボ 勉強会 2021年9月
• メッセージの主な宛先
– ウィンドウ(HWND)
– スレッド
– メッセージキュー経由のシステム通知
• HWNDはメッセージを介して動作
– メッセージの処理は必ず作成したスレッドで行われる
• 別スレッド(別プロセス)からのメッセージ送信も可能
– スレッド外からのメッセージはメッセージキューを経由
– HWND宛てメッセージはHWNDを作成したスレッドで処理
UIスレッドとは
.NETラボ 勉強会 2021年9月
• 同期送信(Send)
– SendMessage 系API
– メッセージ処理を完了するまで帰ってこない
• 同一スレッドからの送信の場合、プロシージャの直接呼出し
• 別スレッドからのSendはメッセージキューを通じて同期化
• 非同期送信(Post)
– PostMessage 系API
– メッセージキューに格納するだけ
– メッセージが処理されたかどうかは呼び出し元では不明
UIスレッドとは-HWNDにメッセージを送るには
.NETラボ 勉強会 2021年9月
• スレッド宛てメッセージ送信
– PostThreadMessage API
• 特定の任意のスレッドにPostする
– 処理するプロシージャがない
• メッセージループ内で独自に処理する必要がある
メッセージループをシステムで代替することはでき
ない
UIスレッドとは-スレッドにメッセージを送るには
.NETラボ 勉強会 2021年9月
• スレッド内オブジェクト宛てメッセージの受入バッファ
– HWND宛てメッセージ(HWND作成スレッドのキューに届く)
– スレッド内で処理してほしいメッセージ(指定スレッドに届く)
• Send または Post でキューに格納
• 原則すべてのメッセージ送信が格納
– 同一スレッド内の Send のみキューを経由せずに直送
• 優先順位付きキューのようなバッファ
– 種別ごとのキューと状態フラグを持つ複合的なバッファ
UIスレッドとは-メッセージキューとは
.NETラボ 勉強会 2021年9月
• メッセージキューの取得優先順位順
1. Sendされたメッセージ(キュー)=QS_SENDMESSAGE
• 同一スレッド内のSendはその場でDispatchされる
2. Postされたメッセージ(キュー)=QS_POSTMESSAGE
3. 入力処理と内部システムイベント=QS_INPUT
4. Sendされたメッセージ(再チェック)= QS_SENDMESSAGE
• 内部処理で生成される場合への対応
5. 無効化領域チェック=QS_PAINT
• 存在すればWM_PAINTを生成
6. タイマー通知チェック=QS_TIMER
• 存在すればWM_TIMERを生成
UIスレッドとは-メッセージキューとは
.NETラボ 勉強会 2021年9月
• 優先順位と状態を持つ特別なバッファ
– 同一優先順位なら原則送信順に処理
– GetMessage/PeekMessage は取得条件を指定可能
• 本来の優先順を無視して取得できる
• メッセージを送る側は順番を想定してはならない
– 別スレッドからのSendより同一スレッド内のSend(直送)が優先
• メッセージを受信する側も受信順などを期待できない
– DOWNがきてUPが来ないこともある
– WM_CLOSE が来ないでいきなり WM_DESTROY が来る
UIスレッドとは-メッセージキューとは
.NETラボ 勉強会 2021年9月
• 本日のゴール
• おことわり
• UIスレッドとは
• まとめ
もくじ
.NETラボ 勉強会 2021年9月
• スレッドには2種類の分類がある
– メインスレッドとそれ以外のスレッド
– UIスレッドとそれ以外のスレッド
まとめ
.NETラボ 勉強会 2021年9月
• メインスレッドの主な役割と特性
– プロセス内で一つだけ
– プロセスの維持
• UIスレッドの主な役割と特性
– メッセージキューからメッセージを取得して適切に処理
– プロセス内に複数作成可能
– UIスレッドはプロセス内に複数作成可能
• バックグラウンド処理でシステム通知を受け取るために分離
– トップレベルウィンドウにしか通知されないメッセージがある
• アパートメントを分離
– 分離するならトップレベルウィンドウレベルが良い
まとめ
.NETラボ 勉強会 2021年9月
• メインスレッドはUIスレッドとは限らない
– (寿命管理上便利だが)メインスレッドである必要性はない
まとめ
.NETラボ 勉強会 2021年9月
UIスレッドは
メッセージループを持つスレッド
と言われるが、正しくは
メッセージキューからメッセージを
取得する必要のある
スレッドのこと
まとめ
ご清聴ありがとうございました
.NETラボ 勉強会 2021年9月
ご清聴ありがとうございました

More Related Content

PDF
GLSLによるシェーダーアートことはじめ
Yoichi Hirata
 
PDF
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
Jun-ichi Sakamoto
 
PDF
ラムダと invokedynamic の蜜月
Taku Miyakawa
 
PDF
Reactive extensions入門v0.1
一希 大田
 
PDF
130821 owasp zed attack proxyをぶん回せ
Minoru Sakai
 
PDF
UWP アプリを JavaScript で作る 3つの方法
Yasuhiko Yamamoto
 
PPTX
async/await のしくみ
信之 岩永
 
PDF
ドメイン駆動設計のためのオブジェクト指向入門
増田 亨
 
GLSLによるシェーダーアートことはじめ
Yoichi Hirata
 
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
Jun-ichi Sakamoto
 
ラムダと invokedynamic の蜜月
Taku Miyakawa
 
Reactive extensions入門v0.1
一希 大田
 
130821 owasp zed attack proxyをぶん回せ
Minoru Sakai
 
UWP アプリを JavaScript で作る 3つの方法
Yasuhiko Yamamoto
 
async/await のしくみ
信之 岩永
 
ドメイン駆動設計のためのオブジェクト指向入門
増田 亨
 

What's hot (20)

PDF
C#次世代非同期処理概観 - Task vs Reactive Extensions
Yoshifumi Kawai
 
PDF
[DL Hacks] code_representation
Deep Learning JP
 
PDF
パターンでわかる! .NET Coreの非同期処理
Kouji Matsui
 
PDF
Oss貢献超入門
Michihito Shigemura
 
PPTX
最近のやられアプリを試してみた
zaki4649
 
PDF
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
kwatch
 
PDF
今日から使おうSmalltalk
Sho Yoshida
 
PDF
Dockerイメージ管理の内部構造
Etsuji Nakai
 
PDF
並行処理初心者のためのAkka入門
Yoshimura Soichiro
 
PDF
インフラCICDの勘所
Toru Makabe
 
PDF
Spring integration概要
kuroiwa
 
PDF
例外設計における大罪
Takuto Wada
 
PPTX
Xamarin で良くやっていたあれを MAUI でする話
m ishizaki
 
PDF
Reactive Programming by UniRx for Asynchronous & Event Processing
Yoshifumi Kawai
 
PDF
Dockerfileを改善するためのBest Practice 2019年版
Masahito Zembutsu
 
PPTX
ESP32特集の内容紹介
Kenta IDA
 
PDF
外部キー制約に伴うロックの小話
ichirin2501
 
PDF
ChatGPT、 何が「できる」「みえる」ようになってきたのか!
Jingun Jung
 
PPTX
DeNA_Techcon2017_DeNAでのチート・脆弱性診断への取り組み
Toshiharu Sugiyama
 
PDF
Project Loom - 限定継続と軽量スレッド -
Yuichi Sakuraba
 
C#次世代非同期処理概観 - Task vs Reactive Extensions
Yoshifumi Kawai
 
[DL Hacks] code_representation
Deep Learning JP
 
パターンでわかる! .NET Coreの非同期処理
Kouji Matsui
 
Oss貢献超入門
Michihito Shigemura
 
最近のやられアプリを試してみた
zaki4649
 
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
kwatch
 
今日から使おうSmalltalk
Sho Yoshida
 
Dockerイメージ管理の内部構造
Etsuji Nakai
 
並行処理初心者のためのAkka入門
Yoshimura Soichiro
 
インフラCICDの勘所
Toru Makabe
 
Spring integration概要
kuroiwa
 
例外設計における大罪
Takuto Wada
 
Xamarin で良くやっていたあれを MAUI でする話
m ishizaki
 
Reactive Programming by UniRx for Asynchronous & Event Processing
Yoshifumi Kawai
 
Dockerfileを改善するためのBest Practice 2019年版
Masahito Zembutsu
 
ESP32特集の内容紹介
Kenta IDA
 
外部キー制約に伴うロックの小話
ichirin2501
 
ChatGPT、 何が「できる」「みえる」ようになってきたのか!
Jingun Jung
 
DeNA_Techcon2017_DeNAでのチート・脆弱性診断への取り組み
Toshiharu Sugiyama
 
Project Loom - 限定継続と軽量スレッド -
Yuichi Sakuraba
 
Ad

Similar to WindowsにおけるUIスレッドの基礎 (16)

PDF
Thread affinity and CPS
Kouji Matsui
 
PDF
async/awaitダークサイド is 何
Kouji Matsui
 
PPTX
Introduction to conccrent_lock
PIXELAcorporation
 
PPTX
非同期処理の基礎
信之 岩永
 
PPTX
わんくま名古屋#28(20130824) c#で、ライフゲームを高速化してみるよ
Yasuhiko Yamamoto
 
PDF
[2000/10] .NET Technical Briefing 2000 / Visual Studio .NET Part I
Tatsuhiko Tanaka
 
PDF
Windows ストア アプリでスレッド間排他処理
Yasuhiko Yamamoto
 
PDF
いまさら恥ずかしくてAsyncをawaitした
Kouji Matsui
 
PDF
Windows 8時代のUXを支える非同期プログラミング
Yuya Yamaki
 
PPTX
An other world awaits you
信之 岩永
 
PDF
これからの「async/await」の話をしよう
Kouji Matsui
 
PDF
Async History in .NET
Takaaki Suzuki
 
PPT
20050903
小野 修司
 
PPTX
C# 8.0 非同期ストリーム
信之 岩永
 
PDF
Mono is Dead
melpon
 
PDF
async/await deep dive
Takaaki Suzuki
 
Thread affinity and CPS
Kouji Matsui
 
async/awaitダークサイド is 何
Kouji Matsui
 
Introduction to conccrent_lock
PIXELAcorporation
 
非同期処理の基礎
信之 岩永
 
わんくま名古屋#28(20130824) c#で、ライフゲームを高速化してみるよ
Yasuhiko Yamamoto
 
[2000/10] .NET Technical Briefing 2000 / Visual Studio .NET Part I
Tatsuhiko Tanaka
 
Windows ストア アプリでスレッド間排他処理
Yasuhiko Yamamoto
 
いまさら恥ずかしくてAsyncをawaitした
Kouji Matsui
 
Windows 8時代のUXを支える非同期プログラミング
Yuya Yamaki
 
An other world awaits you
信之 岩永
 
これからの「async/await」の話をしよう
Kouji Matsui
 
Async History in .NET
Takaaki Suzuki
 
20050903
小野 修司
 
C# 8.0 非同期ストリーム
信之 岩永
 
Mono is Dead
melpon
 
async/await deep dive
Takaaki Suzuki
 
Ad

WindowsにおけるUIスレッドの基礎

  • 1. .NETラボ 勉強会 2021年9月 オンラインは反応見れないし スピーカーさんもその場で拾ってもらえなくて お互いさみしいので、久しぶりに MISAO を動かしてます。 Twitter で #dotnetlab を付けた 発言を拾って画面に表示してます。 一杯書き込んでくれると嬉しいし楽しいです。 画面に出るまで少しタイムラグがあるのでご了承ください。 始める前に…
  • 2. .NETラボ 勉強会 2021年9月 Windowsにおける UIスレッドの基礎 とっちゃん(高萩 俊行) Microsoft MVP for Developer Technologies since 2005 https://github.com/Tocchann/dotnetlab202109
  • 3. .NETラボ 勉強会 2021年9月 • ハンドル – とっちゃん • 主な活動場所 – わんくま同盟掲示板 – MSDNフォーラム – わんくま同盟勉強会(休止中) • お仕事 – ISV • パッケージソフトの開発 • 良くも悪くも昭和のソフトハウ ス – 一応会社員 • Microsoft MVP 歴 – 2005-2008 • Windows – SDK – 2008-2016 • Visual C++ – 2016-2018 • Visual Studio and Development Technologies – 2018-2022 • Developer Technologies 軽く自己紹介
  • 4. .NETラボ 勉強会 2021年9月 Windowsにおける UIスレッドの基礎 とっちゃん(高萩 俊行) Microsoft MVP for Developer Technologies since 2005 https://github.com/Tocchann/dotnetlab202109
  • 5. .NETラボ 勉強会 2021年9月 • 本日のゴール • おことわり • UIスレッドとは • まとめ もくじ
  • 7. .NETラボ 勉強会 2021年9月 • 本日のゴール • おことわり • UIスレッドとは • まとめ もくじ
  • 8. .NETラボ 勉強会 2021年9月 • 基本的に詳しい解説はなし – API、メッセージ、プロシージャとかでてくるけど気にしない • Windows の GUIアプリの話 – コンソールアプリは少し状況が異なる – NTサービスはだいぶ状況が異なる • Native Windows 環境での話 – .NET 環境のUIスレッドも基本的に同じ – 同じOSの上で直接動くアプリ同士なので内部的には大差ない おことわり
  • 9. .NETラボ 勉強会 2021年9月 • 現Win32環境が前提 – 現状の動作は正しいものとして扱う • 動作確認は以下の環境 – Windows 11 21H1 – Surface Book 2 • i7-8650U • Mem16G/SSD 1T • Windows は、搭載メモリなどで動作が変わる – Windows 8 からの挙動 おことわり
  • 10. .NETラボ 勉強会 2021年9月 • 本日のゴール • おことわり • UIスレッドとは • まとめ もくじ
  • 11. .NETラボ 勉強会 2021年9月 • スレッドの種類 • UIスレッドとは UIスレッドとは
  • 12. .NETラボ 勉強会 2021年9月 • スレッドには2種類の分類がある – メインスレッドとそれ以外のスレッド – UIスレッドとそれ以外のスレッド スレッドの種類
  • 13. .NETラボ 勉強会 2021年9月 • メインスレッド – プロセス作成時に作られるスレッド – プロセスに一つだけ存在 – メインスレッドが終了するとそのプロセスは破棄される • サブスレッド – メインスレッド以外のスレッドの総称 – サブスレッドが動いていていてもプロセスは終了できる スレッドの種類
  • 14. .NETラボ 勉強会 2021年9月 • シングルスレッド – メインスレッドのみのプログラム • システムが内部処理用に作るスレッドを除く • マルチスレッド – メインスレッド以外のスレッドがあるプログラム • CreateThread, std::thread, std::async • System.Threading.Tasks.Task スレッドの種類
  • 15. .NETラボ 勉強会 2021年9月 • UIスレッド – プロセスに0個以上存在 – Windowsのメッセージを処理するスレッド – アパートメントスレッドと呼ばれることもある – メインスレッドである必要はない • ワーカースレッド – UIスレッド以外のすべてのスレッド – 非UIスレッドと呼ばれることもある • もしかして、UIスレッドってなくてもいい? スレッドの種類
  • 16. .NETラボ 勉強会 2021年9月 • UIスレッドがないと? – WaitForInputIdle がタイムアウトまで帰ってこない • リファレンスより – Waits until the specified process has finished processing its initial input and is waiting for user input with no input pending, or until the time-out interval has elapsed. • 実際のところ… – プロセスでメッセージを取得(待機)するかタイムアウトまで待 機 • 一般的なアプリではメッセージループに到達するまでに相当 UIスレッドとは-ないとどうなるの?
  • 18. .NETラボ 勉強会 2021年9月 1. コンソールアプリを待機する場合 2. UIスレッドのないアプリを待機する場合 – .NET 5 ランタイムインストーラ • WiX 3.14 で作成 – DLL Injection 対応でマルチプロセス構造 – サブプロセスの待機が WaitForSingleObject » UIスレッドではないメインスレッドのみのプロセス • シンプルなGUIアプリで確認 3. ウィンドウを作ってから1秒待機 4. ウィンドウ作成前に PeekMessage する場合 5. ウィンドウ作成前に MsgWaitForMultipleObjectする場合 WaitForInputIdle の確認
  • 19. .NETラボ 勉強会 2021年9月 • スレッドの種類 • UIスレッドとは UIスレッドとは
  • 20. .NETラボ 勉強会 2021年9月 • UIスレッド – 一般にメッセージループを持つスレッドと言われる – 主にウィンドウメッセージ(HWNDあてメッセージ)を処理 – 他のスレッドやシステムと協調的に動くための根幹を形成する UIスレッドとは
  • 21. .NETラボ 勉強会 2021年9月 • メッセージループとは? – メッセージを処理するループの総称 1. メッセージキューからメッセージを取得 2. メッセージを消化 – 宛先ウィンドウのウィンドウプロシージャにメッセージを送る – スレッド宛てメッセージを処理 3. 繰り返し不要になるまで1,2を繰り返す – 通常 WM_QUIT を取得するまで UIスレッドとは-メッセージループとは
  • 22. .NETラボ 勉強会 2021年9月 • 最小のメッセージループ UIスレッドとは-メッセージループとは // 最小のメッセージループ int MinimumMessageLoop() { MSG msg; // メッセージキューからメッセージを取得 while( GetMessage( &msg, nullptr, 0, 0 ) ) { // (お呪い)入力メッセージを変換 TranslateMessage( &msg ); // msg.hWnd のプロシージャにメッセージを処理させる DispatchMessage( &msg ); } return static_cast<int>(msg.wParam); }
  • 23. .NETラボ 勉強会 2021年9月 • メッセージポンプ – メッセージの取得と処理部分を切り出した部分処理 – PeekMessageでメッセージを取得して、メッセージを消化 – 空になるまで繰り返すことが多い • System.Windows.Forms.Application.DoEvents() など – C++では原則自前実装 • MFC には AfxPumpMessage という1回だけポンプする関数がある UIスレッドとは
  • 24. .NETラボ 勉強会 2021年9月 • メッセージの主な宛先 – ウィンドウ(HWND) – スレッド – メッセージキュー経由のシステム通知 • HWNDはメッセージを介して動作 – メッセージの処理は必ず作成したスレッドで行われる • 別スレッド(別プロセス)からのメッセージ送信も可能 – スレッド外からのメッセージはメッセージキューを経由 – HWND宛てメッセージはHWNDを作成したスレッドで処理 UIスレッドとは
  • 25. .NETラボ 勉強会 2021年9月 • 同期送信(Send) – SendMessage 系API – メッセージ処理を完了するまで帰ってこない • 同一スレッドからの送信の場合、プロシージャの直接呼出し • 別スレッドからのSendはメッセージキューを通じて同期化 • 非同期送信(Post) – PostMessage 系API – メッセージキューに格納するだけ – メッセージが処理されたかどうかは呼び出し元では不明 UIスレッドとは-HWNDにメッセージを送るには
  • 26. .NETラボ 勉強会 2021年9月 • スレッド宛てメッセージ送信 – PostThreadMessage API • 特定の任意のスレッドにPostする – 処理するプロシージャがない • メッセージループ内で独自に処理する必要がある メッセージループをシステムで代替することはでき ない UIスレッドとは-スレッドにメッセージを送るには
  • 27. .NETラボ 勉強会 2021年9月 • スレッド内オブジェクト宛てメッセージの受入バッファ – HWND宛てメッセージ(HWND作成スレッドのキューに届く) – スレッド内で処理してほしいメッセージ(指定スレッドに届く) • Send または Post でキューに格納 • 原則すべてのメッセージ送信が格納 – 同一スレッド内の Send のみキューを経由せずに直送 • 優先順位付きキューのようなバッファ – 種別ごとのキューと状態フラグを持つ複合的なバッファ UIスレッドとは-メッセージキューとは
  • 28. .NETラボ 勉強会 2021年9月 • メッセージキューの取得優先順位順 1. Sendされたメッセージ(キュー)=QS_SENDMESSAGE • 同一スレッド内のSendはその場でDispatchされる 2. Postされたメッセージ(キュー)=QS_POSTMESSAGE 3. 入力処理と内部システムイベント=QS_INPUT 4. Sendされたメッセージ(再チェック)= QS_SENDMESSAGE • 内部処理で生成される場合への対応 5. 無効化領域チェック=QS_PAINT • 存在すればWM_PAINTを生成 6. タイマー通知チェック=QS_TIMER • 存在すればWM_TIMERを生成 UIスレッドとは-メッセージキューとは
  • 29. .NETラボ 勉強会 2021年9月 • 優先順位と状態を持つ特別なバッファ – 同一優先順位なら原則送信順に処理 – GetMessage/PeekMessage は取得条件を指定可能 • 本来の優先順を無視して取得できる • メッセージを送る側は順番を想定してはならない – 別スレッドからのSendより同一スレッド内のSend(直送)が優先 • メッセージを受信する側も受信順などを期待できない – DOWNがきてUPが来ないこともある – WM_CLOSE が来ないでいきなり WM_DESTROY が来る UIスレッドとは-メッセージキューとは
  • 30. .NETラボ 勉強会 2021年9月 • 本日のゴール • おことわり • UIスレッドとは • まとめ もくじ
  • 31. .NETラボ 勉強会 2021年9月 • スレッドには2種類の分類がある – メインスレッドとそれ以外のスレッド – UIスレッドとそれ以外のスレッド まとめ
  • 32. .NETラボ 勉強会 2021年9月 • メインスレッドの主な役割と特性 – プロセス内で一つだけ – プロセスの維持 • UIスレッドの主な役割と特性 – メッセージキューからメッセージを取得して適切に処理 – プロセス内に複数作成可能 – UIスレッドはプロセス内に複数作成可能 • バックグラウンド処理でシステム通知を受け取るために分離 – トップレベルウィンドウにしか通知されないメッセージがある • アパートメントを分離 – 分離するならトップレベルウィンドウレベルが良い まとめ
  • 33. .NETラボ 勉強会 2021年9月 • メインスレッドはUIスレッドとは限らない – (寿命管理上便利だが)メインスレッドである必要性はない まとめ