teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

7

追記

2015/12/12 05:59

投稿

Chironian
Chironian

スコア23274

answer CHANGED
@@ -42,3 +42,14 @@
42
42
  【余談】
43
43
  なんか改行が使いにくくなってますね。>teratail
44
44
  って、 eripongさんが改行方法を書いてくれてました!! ありがとう。
45
+
46
+ ---
47
+ 【追記】
48
+ > 2015-12-07 追記です
49
+ (中略)
50
+ > 2 スレッドAのフォーム作成完了後の処理中に、スレッドBのフォーム作成を実行させるには?
51
+ に今気が付きました。
52
+
53
+ もし、本当に.NETがフォーム生成中(new Form~フォーム表示)の間、排他制御していたら、無理な気がします。
54
+ 確認するために、スレッドAのnew Formの**直前**でSleep(5)としてみて、スレッドAとスレッドBのフォーム作成タイミングが逆にならないでしょうか? もし、そうなるなら、これは回避できないように感じます。
55
+ 後は.NETのバージョンを上げてみるくらいしか思いつきませんでした。

6

typo

2015/12/12 05:58

投稿

Chironian
Chironian

スコア23274

answer CHANGED
@@ -13,7 +13,7 @@
13
13
 
14
14
  ---
15
15
  【追記】
16
- [リンク内容](https://msdn.microsoft.com/ja-jp/library/system.windows.forms.application.run%28v=vs.110%29.aspx)Application.Run()は「現在のスレッドで標準のアプリケーション メッセージ ループの実行を開始します。」と記載されてました。
16
+ [Application.Run()](https://msdn.microsoft.com/ja-jp/library/system.windows.forms.application.run%28v=vs.110%29.aspx)は「現在のスレッドで標準のアプリケーション メッセージ ループの実行を開始します。」と記載されてました。
17
17
  つまり、ここでメッセージ・ループを回すので、それぞれのスレッドにてメッセージ・ループを回っていますね。
18
18
 
19
19
  さて、普通にメッセージ・ループを回すだけであれば特に他のスレッドと同期させる必要はありません。

5

追記

2015/12/04 05:50

投稿

Chironian
Chironian

スコア23274

answer CHANGED
@@ -12,7 +12,33 @@
12
12
  nobysanzさんがおっしゃっているような動きをするということは、C#処理系側でスレッド安全になるよう排他制御している可能性はあると思います。
13
13
 
14
14
  ---
15
+ 【追記】
16
+ [リンク内容](https://msdn.microsoft.com/ja-jp/library/system.windows.forms.application.run%28v=vs.110%29.aspx)Application.Run()は「現在のスレッドで標準のアプリケーション メッセージ ループの実行を開始します。」と記載されてました。
17
+ つまり、ここでメッセージ・ループを回すので、それぞれのスレッドにてメッセージ・ループを回っていますね。
15
18
 
19
+ さて、普通にメッセージ・ループを回すだけであれば特に他のスレッドと同期させる必要はありません。
20
+ ということは、特に排他制御していないにも関わらず、スレッドAは起動から約15mSecで処理を開始し、スレッドBは起動から約30mSecで処理を開始していることになります。
21
+ まるでシングル・スレッド動作してますね。マルチコアでそれは考えにくいです。
22
+
23
+ ところで、new Form;は、C#のフォーム・クラスのインスタンスを生成します。ここでCreateWindow()されているかも知れませんが、まだメッセージ・ループを周り始めていませんので、実際のウィンドウの生成・描画は始まっていません。Run()内でウィンドウ・メッセージを処理しつつ、生成・描画が進行します。
24
+
25
+ もしも、new Form;でMutexを獲得し、Run()でウィンドウが本当に生成・描画されてから解放しているなんてことになっていたと仮定すると、説明が付きますね。
26
+ (同じスレッド内で複数new Form;する時、同じスレッドが既にMutexを獲得しているケースではブロックされませんから。)
27
+
28
+ (スレッドA開始)と(スレッドB開始)はそれぞれのスレッド内で出力してますか? それとも、各スレッドを起動したスレッドで出力してますか?
29
+ もし、後者なら、試しに各スレッドでnew Form;を行う前にもログ出力してみませんか?
30
+ スレッドに制御が渡ってから、new Form;が完了するまでの時間が気になります。
31
+ もし、それが片方は15mSec、もう一方が30mSecで安定しているようでしたら、.NETが何か15mSec単位のタイムスケジュールに同期するような処理をnew Form;に仕込んでいることになります。
32
+ .NETは思わぬところで、異常な処理をしていることがありましたので、油断できません。
33
+
34
+ あっ、異常な処理で、思い出しました。その異常な処理で困ったのは.NETのファイル・ストリームでした。ファイルが大きくなると、アペンド処理が異常に遅くなるという本当に不可解な現象でした。Windows APIを直接呼び出して回避したことがあります。
35
+
36
+ もし、ログを同じファイルへファイル・ストリームを使って出力しているのでしたら、それが何か悪さしていることも考えられます。当然排他制御されてますし。
37
+ もし、同じファイルに出力しているようでしたら、別ファイルに出してみるのも手です。
38
+ でも、.NET経由なので安心はできませんが...
39
+
40
+ ---
41
+
16
42
  【余談】
17
43
  なんか改行が使いにくくなってますね。>teratail
18
44
  って、 eripongさんが改行方法を書いてくれてました!! ありがとう。

4

追記

2015/12/04 05:49

投稿

Chironian
Chironian

スコア23274

answer CHANGED
@@ -13,4 +13,6 @@
13
13
 
14
14
  ---
15
15
 
16
+ 【余談】
16
- 【余談】なんか改行が使いにくくなってますね。>teratail
17
+ なんか改行が使いにくくなってますね。>teratail
18
+ って、 eripongさんが改行方法を書いてくれてました!! ありがとう。

3

typo

2015/12/04 03:40

投稿

Chironian
Chironian

スコア23274

answer CHANGED
@@ -1,4 +1,5 @@
1
1
  > C#で2つのスレッドでフォームを表示する処理
2
+
2
3
  これって普通にできるのでしたっけ?
3
4
 
4
5
  Windowsのウィンドウを別スレッドで生成し制御する場合、それぞれのスレッドでメッセージ・ループを回す必要があります。nobysanzさんがどのような方法でフォームを生成されたのか分かりませんが、メッセージ・ループを回してくれるような生成方法で生成されたでしょうか?(すいません、C#ではやったことないので、C#で出来るかどうかさえ分かりません。C/C++ではできますし、やったことありますが。)
@@ -8,4 +9,8 @@
8
9
 
9
10
  そして、C#の場合、「[フォーム コントロールへのアクセスは、本質的にスレッド セーフではありません。](https://msdn.microsoft.com/ja-jp/library/ms171728%28v=vs.110%29.aspx)」となってます。同じフォームのコントロールを別スレッドからアクセスする場合は排他制御等が必要と言う意味ですが、異なるフォーム同士でもフォームを管理しているデータが本当にスレッド安全なのか、少し心配です。
10
11
 
11
- nobysanzさんがおっしゃっているような動きをするということは、C#処理系側でスレッド安全になるよう排他制御している可能性はあると思います。
12
+ nobysanzさんがおっしゃっているような動きをするということは、C#処理系側でスレッド安全になるよう排他制御している可能性はあると思います。
13
+
14
+ ---
15
+
16
+ 【余談】なんか改行が使いにくくなってますね。>teratail

2

補足的修正

2015/12/04 03:35

投稿

Chironian
Chironian

スコア23274

answer CHANGED
@@ -4,7 +4,7 @@
4
4
  Windowsのウィンドウを別スレッドで生成し制御する場合、それぞれのスレッドでメッセージ・ループを回す必要があります。nobysanzさんがどのような方法でフォームを生成されたのか分かりませんが、メッセージ・ループを回してくれるような生成方法で生成されたでしょうか?(すいません、C#ではやったことないので、C#で出来るかどうかさえ分かりません。C/C++ではできますし、やったことありますが。)
5
5
 
6
6
  もし、そこまでされてないのであれば、それぞれのフォームはメイン・スレッドで生成される筈です。
7
- でないと、メイン・スレッドで回っている[メッセージ・ループがそのウィンド宛のメッセージを処理しない筈](https://msdn.microsoft.com/ja-jp/library/cc364699.aspx)です。
7
+ でないと、メイン・スレッドで回っている[メッセージ・ループがそのウィンド宛のメッセージを受け取れない筈](https://msdn.microsoft.com/ja-jp/library/cc364699.aspx)です。
8
8
 
9
9
  そして、C#の場合、「[フォーム コントロールへのアクセスは、本質的にスレッド セーフではありません。](https://msdn.microsoft.com/ja-jp/library/ms171728%28v=vs.110%29.aspx)」となってます。同じフォームのコントロールを別スレッドからアクセスする場合は排他制御等が必要と言う意味ですが、異なるフォーム同士でもフォームを管理しているデータが本当にスレッド安全なのか、少し心配です。
10
10
 

1

補足的修正

2015/12/04 03:26

投稿

Chironian
Chironian

スコア23274

answer CHANGED
@@ -4,7 +4,7 @@
4
4
  Windowsのウィンドウを別スレッドで生成し制御する場合、それぞれのスレッドでメッセージ・ループを回す必要があります。nobysanzさんがどのような方法でフォームを生成されたのか分かりませんが、メッセージ・ループを回してくれるような生成方法で生成されたでしょうか?(すいません、C#ではやったことないので、C#で出来るかどうかさえ分かりません。C/C++ではできますし、やったことありますが。)
5
5
 
6
6
  もし、そこまでされてないのであれば、それぞれのフォームはメイン・スレッドで生成される筈です。
7
- でないと、メイン・スレッドで回っている[メッセージ・ループがメッセージを処理しない筈](https://msdn.microsoft.com/ja-jp/library/cc364699.aspx)です。
7
+ でないと、メイン・スレッドで回っている[メッセージ・ループがそのウィンド宛のメッセージを処理しない筈](https://msdn.microsoft.com/ja-jp/library/cc364699.aspx)です。
8
8
 
9
9
  そして、C#の場合、「[フォーム コントロールへのアクセスは、本質的にスレッド セーフではありません。](https://msdn.microsoft.com/ja-jp/library/ms171728%28v=vs.110%29.aspx)」となってます。同じフォームのコントロールを別スレッドからアクセスする場合は排他制御等が必要と言う意味ですが、異なるフォーム同士でもフォームを管理しているデータが本当にスレッド安全なのか、少し心配です。
10
10