C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト


(過去ログ 17 を表示中)
■6798 / )  Re[6]: 別スレッドでShowDialogしたフォームのクローズ
□投稿者/ 困ったちゃん (6回)-(2007/08/23(Thu) 23:29:22)
No6791 (まどか さん) に返信
> 普通は時間のかかる「処理」を別スレッド化して、GUIメインスレッドは通常の入力待ち状態(普通にフォームが表示されている状態)にさせます。
> で、スレッドからの通知を受けて表示を更新します。

おっしゃることはよく分かります。No6760 のコードは、できるだけ簡潔に記述しようとしたため、Form1に重たい処理が載ってしまいましたが、
もとよりGUIメインスレッドの方を重くすることが主旨ではありません。ワーカースレッドに振っても構いません。
そもそもの動機は、多回数の繰り返し処理の途中情報を表示するフォームを、好きなときに開いたり閉じたりしたいという点でした。
その代替手段はいろいろ考えられるのでしょうが、それはまた別問題として、このサンプルコードでフリーズしてしまう理由がどうにも釈然と
しないので、お尋ねしたような次第です。

#ここで各方面からツッコミが入る前に、一点、イクスキューズを。
好きなときにButton1を押せるようにするには、Form1.Button2_Click のループ中にApplication.DoEvents()を挿入すべきですが、
そうすると、Form2のクローズボタンを押してもフリーズしにくくなります(ただし数回〜数十回程度に1回はフリーズします)。
サンプルコードでは、再現性を損なわず問題点が際立つように、DoEventsは省きました。

No6793 (れい さん) に返信
> フォームが閉じて作成元スレッドはメッセージを読みにいかなくなるのに
> 他のスレッドがInvokeでメッセージを送り、完了を待つからです。

まさにその辺りの事情を詳しく知りたいのです。解説ドキュメントなどご存知でしたらご教示いただけませんでしょうか。

> Invokeではなく、
> BeginInvokeにすれば完了を待たないので解決するかと思います。

InvokeをBeginInvokeに書き換えると、速くなりすぎてForm2のクローズボタンを掴まえられなくなりました。^^;
何か工夫して確認にトライしてみます。
ただ、このサンプルコードでは戻り値を必要としませんでしたが、一般にはFunctionをInvokeしたいケースも多々あろうかと存じます。
この手の問題の正統?な解決策がありましたら、併せてお願いいたします。

Form2のClosingイベントでフラグを立てて、Invokeを阻止すると効果があることは確認できたのですが、それで万全なのかが確信できないでいます。
返信 編集キー/


管理者用

- Child Tree -