回答編集履歴

6

分かり難いので修正

2016/09/19 15:03

投稿

Chironian
Chironian

スコア23272

test CHANGED
@@ -54,18 +54,18 @@
54
54
 
55
55
   ビックリですね。でも、絶対に説明は付く筈です。
56
56
 
57
-  task.wait()はスレッド終了だけを待っていると思ってましたが、そうではないということかも知れません。
57
+  task.Wait()はスレッド終了だけを待っていると思ってましたが、そうではないということかも知れません。task.Wait()がCOMメッセージを処理しつつスレッド終了を待つのであれば説明が付きますね。
58
58
 
59
59
 
60
60
 
61
61
   確かC#のTrace.WriteLine()を使えばデバッグ出力(Windows APIのOutputDebugString)ができたと思います。
62
62
 
63
-  これを、Task.Run()で起動するサブスレッドの中(*1)と、Task.Run()の後task.Wait()の前(*2)においてみると確認できるのではないかと思います。
63
+  これを、Task.Run()で起動するサブスレッドの中(*1)と、Task.Run()の後task.Wait()の前(*2)においてみると確認できると思います。
64
64
 
65
-  task.Wait()内でCOMメッセージ処理されているなら(*2)→(*1)の順で表示される筈です。(*2)の後でサブスレッドがメイン・スレッド処理されているので、task.Wait()しないと言うわけです。
65
+  task.Wait()内でCOMメッセージ処理されているなら(*2)→(*1)の順で表示される筈です。この場合、(*2)の後でサブスレッド内のCOM処理がメイン・スレッドで実行されているということになるので、task.Wait()がCOMメッセージを処理ている以外に考えられないと思います。
66
66
 
67
67
 
68
68
 
69
-  逆の順で表示されたら、う~ん頭痛いです。Task.Run()の頭はメイン・スレッドで実行しているとか、GetCurrentThreadId()などが疑わしくなります。ちょっとそれは考えにくいで
69
+  逆の順で表示されたら、う~ん頭痛いです。Task.Run()の頭はメイン・スレッドで実行しているとか、GetCurrentThreadId()などが疑わしくなりますが、流石にそれはような気がするので。
70
70
 
71
71
 

5

質問の追記を見て追記

2016/09/19 15:03

投稿

Chironian
Chironian

スコア23272

test CHANGED
@@ -44,4 +44,28 @@
44
44
 
45
45
  メイン・スレッドのIDを表示してみたらどうでしょうか?(もちろん、COMを経由しないで直接)
46
46
 
47
- メイン・スレッドはtask.wait()でブロックされているので、これを使ってCOMメッセージを処理しているとしたらデッロックする筈なので、COMへの要求は別のスレッドで実行されている筈です。
47
+ メイン・スレッドはtask.wait()でブロックされているので、これを使ってCOMメッセージを処理しているとしたらデッロックする筈なので、COMへの要求は別のスレッドで実行されている筈です。
48
+
49
+
50
+
51
+ ---
52
+
53
+ 【質問の追記を見て追記】
54
+
55
+  ビックリですね。でも、絶対に説明は付く筈です。
56
+
57
+  task.wait()はスレッド終了だけを待っていると思ってましたが、そうではないということかも知れません。
58
+
59
+
60
+
61
+  確かC#のTrace.WriteLine()を使えばデバッグ出力(Windows APIのOutputDebugString)ができたと思います。
62
+
63
+  これを、Task.Run()で起動するサブスレッドの中(*1)と、Task.Run()の後task.Wait()の前(*2)においてみると確認できるのではないかと思います。
64
+
65
+  task.Wait()内でCOMメッセージ処理されているなら(*2)→(*1)の順で表示される筈です。(*2)の後でサブスレッドがメイン・スレッド内で処理されているので、task.Wait()しかないと言うわけです。
66
+
67
+
68
+
69
+  逆の順で表示されたら、う~ん頭痛いです。Task.Run()の頭はメイン・スレッドで実行しているとか、GetCurrentThreadId()などが疑わしくなります。ちょっとそれは考えにくいです。
70
+
71
+

4

微修正

2016/09/19 12:47

投稿

Chironian
Chironian

スコア23272

test CHANGED
@@ -42,6 +42,6 @@
42
42
 
43
43
  COMオブジェクト生成時に別スレッドを起動し、その中で勝手にメッセージ・ループを回り、それを使って同期しているならデッドロックしないです。
44
44
 
45
- Button1, Button2を処理しているスレッドのIDを表示してみたらどうでしょうか?(もちろん、COMを経由しないで直接)
45
+ メイン・スレッドのIDを表示してみたらどうでしょうか?(もちろん、COMを経由しないで直接)
46
46
 
47
- このスレッドはtask.wait()でブロックされているので、これを使ってCOMメッセージを処理しているとしたらデットロックする筈なので、COMへの要求は別のスレッドで実行されている筈です。
47
+ メイン・スレッドはtask.wait()でブロックされているので、これを使ってCOMメッセージを処理しているとしたらデットロックする筈なので、COMへの要求は別のスレッドで実行されている筈です。

3

追記

2016/09/19 01:47

投稿

Chironian
Chironian

スコア23272

test CHANGED
@@ -32,6 +32,16 @@
32
32
 
33
33
 
34
34
 
35
+ ---
36
+
37
+ 【追記】
38
+
39
+ STAではCOMオブジェクト生成側のメッセージ・ループ(今回の場合メイン・スレッド)を使って同期しているように私も理解してますが、それが誤りかも知れません。
35
40
 
36
41
 
37
42
 
43
+ COMオブジェクト生成時に別スレッドを起動し、その中で勝手にメッセージ・ループを回り、それを使って同期しているならデッドロックしないです。
44
+
45
+ Button1, Button2を処理しているスレッドのIDを表示してみたらどうでしょうか?(もちろん、COMを経由しないで直接)
46
+
47
+ このスレッドはtask.wait()でブロックされているので、これを使ってCOMメッセージを処理しているとしたらデットロックする筈なので、COMへの要求は別のスレッドで実行されている筈です。

2

追記

2016/09/19 01:45

投稿

Chironian
Chironian

スコア23272

test CHANGED
@@ -19,3 +19,19 @@
19
19
  モーダル・ダイアログを表示していても、当たり前ですがメッセージ・ループは回っています。でないとモーダル・ダイアログを操作できませんので。
20
20
 
21
21
  従って、COMのメッセージも処理されている筈です。
22
+
23
+
24
+
25
+ ---
26
+
27
+ 違いました。
28
+
29
+ モーダル・ダイアログ表示前の`task.Wait();`でメッセージ・ループを回っているスレッドがブロックされているのになぜGetThreadID()が処理されるのか?ですね。
30
+
31
+ 確かによく分からんですね。
32
+
33
+
34
+
35
+
36
+
37
+

1

追加

2016/09/19 01:25

投稿

Chironian
Chironian

スコア23272

test CHANGED
@@ -1,4 +1,12 @@
1
1
  こんにちは。
2
+
3
+
4
+
5
+ > STAスレッドに属するCOMオブジェクトのメソッドが別のスレッドから呼び出された場合、STAスレッドのメッセージループを利用してメソッド呼び出しが同期されるような機構が働くため、Task内での呼び出しにも関わらずGetThreadIDの実行はメインスレッドで行われたものと考えられます。
6
+
7
+
8
+
9
+ 私もそう思います。
2
10
 
3
11
 
4
12
 
@@ -6,7 +14,7 @@
6
14
 
7
15
 
8
16
 
9
- そのな
17
+ しかし、ちらす。
10
18
 
11
19
  モーダル・ダイアログを表示していても、当たり前ですがメッセージ・ループは回っています。でないとモーダル・ダイアログを操作できませんので。
12
20