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

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

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

Re[9]: Invoke 中に FormClosed にな [1]


(過去ログ 126 を表示中)

[トピック内 26 記事 (21 - 26 表示)]  << 0 | 1 >>

■75213 / inTopicNo.21)  Re[5]: Invoke 中に FormClosed にな
  
□投稿者/ 774RR (237回)-(2015/03/06(Fri) 09:07:37)
# 俺の当初想定していた以上に盛り上がっているのはなぜ?

No75205 yukihiro さん
> FormClosingイベント中ではまだフォームが消えるかどうかわからないので、
> そこでそんなことをやるべきじゃない、と直観的には感じます。
これは単に FormClosing をどう捕らえるか感じ方の問題だと思うわけですが。

e.Cancel に入れる値で「閉じるか閉じないかを選択するイベント」と考えるなら
「まだ消えない」で正解ですし

常に e.Cancel = false; で戻る前提で考えれば
「閉じる処理の一連の流れの中で UI 部品が Dispose される前であることが確定しているイベント」
と考えることができるわけで、俺の考えはこっちです。

No75206 Azulean さん
ご提案を試してみます(って今日は会議が入っているので来週になってしまいますが)

引用返信 編集キー/
■75260 / inTopicNo.22)  Re[6]: Invoke 中に FormClosed にな
□投稿者/ 774RR (239回)-(2015/03/09(Mon) 14:10:43)
75206 のコードでとりあえずうまく行っているようにみえます。
見えるのですが System.Diagnostics.Debug.WriteLine で動作ログを確認したところ
SafeInvoke されるハンドラの入口 ->
  FormClosing -> FormClosed ->
    SafeInvoke 内部で IsDisposed 検出 -> SafeInvoke されるハンドラ出口
なる動作が発生していて、これは Control.Invoke と大差ないことになります。

俺の理解が足らないのか微妙に納得できていません。
これってつまり this == Form1 の死活を見ているわけですよね。
this が生きていて this.label1 が死んでいる状況がもしあればまずいのですが
ありうるのでしょうか?
無い(ことが何かで担保できる)のであれば納得できそうです。

75188 のコードの意図は
this が死んでいたら InvalidOperationException
this.label1 が死んでいたら ObjectDisposedException
Invoke 中に this と this.label1 のかたっぽだけ死ぬか、両方が死ぬかは不明
なので IsDisposed でかたっぽだけチェックしても無駄っぽいから IsDisposed は略して両方 catch
だと思うのです。これには大いに納得できるのですが。

# んで、両方とも FormN の作者は各フォームで毎回 IsDisposed チェックをしなくてよい
# 同じこと何度も書かなくてよいのでダサくない、っと。

引用返信 編集キー/
■75270 / inTopicNo.23)  Re[7]: Invoke 中に FormClosed にな
□投稿者/ Azulean (451回)-(2015/03/09(Mon) 18:03:39)
No75260 (774RR さん) に返信
> これってつまり this == Form1 の死活を見ているわけですよね。
> this が生きていて this.label1 が死んでいる状況がもしあればまずいのですが
> ありうるのでしょうか?
> 無い(ことが何かで担保できる)のであれば納得できそうです。

referencesource.microsoft.com で Control の Dispose メソッドの実装を読む限り、ご指摘の状況はあり得ると思います。(考慮漏れでした…)
その短い隙間も担保するのであれば、_referenceControl.IsDisposed || _referenceControl.IsDisposing の条件であれば何とかなりそうです。
http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/Control.cs,5893
(この Dispose メソッドの controlCollection に対する Dispose が件の label1 に対する Dispose に至るはず)


Invoke だとどうしても No75188 のように 例外キャッチを避けられません。
No75206 のコードは、Invoke を使わないことで例外キャッチを避けようとするアプローチとして用意しました。
ObjectDisposedException も InvalidOperationException もむやみにキャッチすると本当の障害を追えなくなる可能性があるので、 No75206 の案+ IsDisposing を見るように変更したものが良いかなと個人的に思っています。
引用返信 編集キー/
■75273 / inTopicNo.24)  Re[7]: Invoke 中に FormClosed にな
□投稿者/ なちゃ (28回)-(2015/03/09(Mon) 18:27:32)
No75260 (774RR さん) に返信
> これってつまり this == Form1 の死活を見ているわけですよね。
> this が生きていて this.label1 が死んでいる状況がもしあればまずいのですが
> ありうるのでしょうか?
> 無い(ことが何かで担保できる)のであれば納得できそうです。

スレッド切り替えた後なので、全体で見て先か後かどちらかしかないと思いますよ。
※普通であればDisposeの途中でスレッド切り替えは発生しない
引用返信 編集キー/
■75275 / inTopicNo.25)  Re[8]: Invoke 中に FormClosed にな
□投稿者/ Azulean (452回)-(2015/03/09(Mon) 18:41:03)
No75273 (なちゃ さん) に返信
> スレッド切り替えた後なので、全体で見て先か後かどちらかしかないと思いますよ。
> ※普通であればDisposeの途中でスレッド切り替えは発生しない

確かに。orz
引用返信 編集キー/
■75276 / inTopicNo.26)  Re[9]: Invoke 中に FormClosed にな
□投稿者/ 774RR (241回)-(2015/03/10(Tue) 09:19:23)
referencesource を読解することで
・ Dispose が一括して行われるというか
・ Dispose 処理中にスレッド再入ポイントが無いというか
ゆえに Dispose 中に処理が俺の書いたハンドラに達することが無い
のが判断できるようなら No 75206 の SafeInvoke 採用決定です。
IsDisposing のチェックも要らないと思います。

# 正直なところ自分で referencesource を読解する必然を感じないというか面倒というか
# いや、必要ならやりますけど・・・

相談してよかったです。
解決済み
引用返信 編集キー/

<前の20件
トピック内ページ移動 / << 0 | 1 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -