人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

【Microsoft VisualC# 2008】プログラム処理中は操作禁止ダイアログを表示し、
処理が終わった後にフラグをおろしてダイアログを閉じる処理を作りたい。そこで以下のようなコーディング
を行ったのですが、Debugモードでは期待通りの動作をしてくれたものの、
Releaseモードでは、操作禁止ダイアログが表示されたままになりました。
この問題についての指摘とアドバイスを下さい。宜しくお願いします。

public Boolean bThreadFlag = false;
private Thread mtestThread;

private void startThread(){

bThreadFlag = true;
mtestThread = new Thread(new ThreadStart(testRun));
mtestThread.SetApartmentState(ApartmentState.STA);
mTestThread.Start();

}
private void testRun{

//ダイアログ表示
while(bThreadFlag){
//処理中
}
//ダイアログ終了
}

private void プログラム計算処理(){

//外部とのやり取りをする処理

//フラグを落とす
bThreadFlag = false;
}

●質問者: harunoharuno
●カテゴリ:コンピュータ インターネット
✍キーワード:C# Microsoft void おろし アドバイス
○ 状態 :終了
└ 回答数 : 6/6件

▽最新の回答へ

1 ● SweetSmile1978
●50ポイント

処理を別スレッドで行うとき、

ユーザインターフェースの操作を

そのスレッドで行うべきではありません。

この場合であれば Testrun は別スレッドとなるので、

testrun 内でユーザインターフェースに関する操作を行うべきではありません。

これは基本事項です。

別スレッドで処理中に何も操作をできないようにするのなら

別スレッドで処理を開始する前、

この例で言うなら startThread メソッドの

mTestThread.Start();

の手前で別に作成した閉じることのできないフォームを表示し、

別スレッドでの処理が終わるまで待機します。

別スレッドでの処理が完了したら表示したダイアログをとじます。

別スレッドでの処理と終了までの大気については

http://msdn.microsoft.com/ja-jp/library/ms228969(v=VS.90).aspx

この項目を読めばよいと思います。

おおざっぱにぱっと考えたことを書いたので

きちんと動く物を作るにはもうすこし苦しんでもらうことになるかもしれません。

ただ、処理中に何もできないようにするのなら、

あえて別スレッドにする必要はないかと思います。

// ユーザが閉じることのできないダイアログを表示

// なにか処理

// 表示したダイアログを表示

だけでいけるのではないでしょうか。

◎質問者からの返答

回答有難う御座います。

補足いたします。

以下二つのプロセスがあり、次に示す流れで動作します。

・サブGUIスレッド(操作禁止ダイアログ)

・メインスレッド(メイン処理)

「処理の流れ」

1:メインスレッドがユーザの操作を受け付ける

2:サブGUIスレッドが進捗表示する

3:メインスレッドが処理を実行する

4:メインスレッドが処理を完了した段階で、サブGUIスレッドの中止フラグをたてる。


曖昧な説明で申し訳ありません。

以下の処理は、メインスレッドから行う処理になります。

private void プログラム計算処理(){

//外部とのやり取りをする処理

//フラグを落とす

bThreadFlag = false;

}


2 ● 勇者よっしー
●100ポイント

ウィンドウ制御は基本的にイベントドリブン。

フラグに頼る限り問題は起きると思います(ここを乗り切ったとしても、ちょっと処理を入れたりバグ迂回したりしたらまた問題噴出すると思います)。

操作禁止ダイアログを作成した時にウィンドウハンドルを保持しておいて、計算が終わったらPostMessage()でメッセージを飛ばし、操作禁止ダイアログがそのメッセージを受け取ったら終了する。

という処理にしない限り、この場を乗り切ったとしてもバージョンアップ時などで問題が起き、そのたびに悩むだろうと思われます。

---

「2:サブGUIスレッドが進捗表示する」のやり方も気になりますね。

あんまり細かいタイミングで表示をしてると、その表示だけでCPUを使い過ぎて重くなる事があります。

・メインスレッドで5?10%単位でサブGUIに計算結果を送る

・サブGUIスレッドでタイマーを実装し、ある程度の単位の時間で進捗具合を取得して表示する

のどちらかでないと、重くなりそうな気がします。

http://yokohama.cool.ne.jp/chokuto/urawaza/api/PostMessage.html

◎質問者からの返答

回答有難う御座います。

質問当初、サブGUIスレッドに対してデータ更新通知などを出してあげれば、サブGUIスレッドから操作禁止ダイアログを終了できると考えていたのですが、、サブGUIスレッドに対してデータ更新を伝える方法はないでしょうか?

(操作禁止ダイアログのウインドハンドルは編集なしに取得できない状態です。)


3 ● SweetSmile1978
●100ポイント

コメントとしてかけないのでこっちに。

はっきりとした根拠を持って言うわけではないのですが、

独立したダイアログと言っても、

GUI関連は全部一つのスレッドで処理した方が良いかなって気はします。

操作禁止ダイアログはメインスレッド(UIスレッド)で表示し、

メインスレッドで行っている処理を別スレッドで行い、

必要に応じて、操作禁止ダイアログ.begininvoke で

進捗状況更新するのではだめなんでしょうか。

http://blogs.msdn.com/b/nakama/archive/2009/04/07/part-3-ui.aspx

◎質問者からの返答

回答有難う御座います。

あとで試してみます。

(回答回数増やしました)


4 ● k-tan2
●300ポイント ベストアンサー

http://msdn.microsoft.com/ja-jp/library/aa289523(v=vs.71).aspx#vbtchusingthreadsanchor7

このあたりを参考に


ループの場所で

System.Windows.Forms.Application.DoEvents();

とかで、明示的に他のイベントを発生可能なようにしてやらないと

駄目だったはずです。

デバッグモードのときは、デバッグする必要性があるので

そういうのを入れなくてもイベントが発生するようになってるので

動作してるんだと思います。

◎質問者からの返答

ずばり回答でした。ありがとうございます。


5 ● 勇者よっしー
●50ポイント

>サブGUIスレッドに対してデータ更新を伝える方法はないでしょうか?

>(操作禁止ダイアログのウインドハンドルは編集なしに取得できない状態です。)

ウィンドウハンドルは取得しておきましょう。

今回は「計算結果が取得できるまでウィンドウを出しておく」という処理ですが、この先ダイアログを閉じる契機なんていくらでも増えると思いますよ。

計算が何の計算なのか判らないので憶測で書きますが、計算ミス、データ取得先が壊れた、メモリ取得エラー、計算元データが入ってるファイル読み取り不可、データ矛盾、などなど、エラールートを考えたら「計算が終わったらダイアログを閉じる」という単純な作りには出来ないと思います。

ウィンドウハンドルを取る・取らないに関わらず、編集は絶対にするのだから、取得しておかないと、今回を乗り切ったとしても乗りきれるだけで今後が苦しくなる一方だと思いますよ。

あと、編集内容はたった2ラインですよね?現在ローカルで取得してるウィンドウハンドルをカットして、クラス定義の場所にペーストする、たったこれだけのエディットを何故「編集が必要」と抵抗してしまうのでしょうか。

ウィンドウハンドルをとったら、前回書いたPostMessage()関連でイベントを渡せばほぼ解決です。

http:///

◎質問者からの返答

yossiy7さんの回答についてお返事します。

1:

操作禁止ダイアログの編集は共通部品なので編集しずらい都合があります。

そのため検討の優先順位は

ややさげています。

ですが、「ウインドウズハンドルを受け取る方法を提供してもらう

ことができれば」「Postの受け口を作ってもらえれば」

間違いのない方法なのでこちらのアプローチも心見てみます。

2:

細かい進捗の更新をしたことがありますが、描画が追いつかないということがありました。

ご助言どおり、感覚を適当にあけるように注意します。


1-5件表示/6件
4.前の5件|次5件6.
関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ