- - PR -
Forms.Control継承型のファイナライゼーション
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2007-01-06 10:38
囚人さん、Jittaさん、返答ありがとうございます。
リンク先を参考にさせていただきます。 ちなみにテストのためには以下のようなコードを書いていたので、 GCの対象となりFinalizeの呼び出しも起こりました。
「ウィンドウハンドルが関連付けられ」ているのは、 ShowメソッドでフォームをロードしてからCloseするまでですね。 | ||||
|
投稿日時: 2007-01-12 06:37
別スレッドから直接いじれないうんぬんの話はWindowと絡んでいて,
> 1.Finalizeメソッドの呼び出しはCLR内部の専用スレッドが行う。 専用スレッドは,(UIスレッドとは別スレッドなので) UIスレッドが作成したWindowは,直接いじれないので, dedicated finalizer thread側(CLR側)は, SendMessageなどで命令をWindowに投げてやるわけです。 (BeginInvokeを使うのと似た理屈) ただ, 対象のオブジェクトがロック状態/ビジー状態だと, 処理されなくて制御がもどってこなくなります。 で,しょうがないので, .NET では,オブジェクトがロック状態でも, 優先度が上がっているスレッドからのものは優先して処理するようになっています。 で, ファイナライズ専用のスレッドの priority を上げておくことによって ブロックされないようにしているわけです。 | ||||
|
投稿日時: 2007-01-12 11:49
すみません、この辺りの情報が載っているところを教えていただけないでしょうか? これは、lockなどでロックされている箇所でも、同じオブジェクトをロックする、 後から来た優先度の高いスレッドによって、割り込まれる可能性があるということ でしょうか? | ||||
|
投稿日時: 2007-01-12 14:59
一応
Threading Model の部分の Reentrancy and Locking の箇所をよりどころにしています。 簡訳: CLRのロック機能は,皆さんが予想するのとはちょっと違った振る舞いをします。 ロックを要求する時,スレッドは実行を完全に止めると思うでしょう。 実際は,そのスレッドは,high priorityメッセージを受け続け処理続けます。 で,以下に理由が続きます。 検証コードですが,これでOKなのかなぞですが,
で, SomeType is being finalized. This is the last line. の順で出力されます。なので,ロックされていても, ファイナライズされているんじゃないかと。 ただ,SomeType が, スレの上の方で出てきたように Formを継承していて, 一度st.Show()したりすると,(st.Hide()しても) そもそもGCの対象にならないようなので 素通りしてしまうんですけどね...(順番が逆になる) | ||||
|
投稿日時: 2007-01-12 15:10
Main内の
Monitor.Enter(st); がそもそも効いていないのでないか?という疑問は,例えば,
とすると,デッドロックを起こすので,Main側のロックは効いています。 | ||||
|
投稿日時: 2007-01-12 15:20
よく考えると,検証にはなってないか。
上の二つのコードは忘れてください。 [追記] Finalize内でロックをかけれないというのは, 別スレッドがFinalizeを呼んでいるということで, 直接,finalizer thread が呼んでいるということですね。 やっぱり, NativeWindow絡みでやらないとよくわからないということかな。 ただ,ファイナライザを呼び出せないんですよね。 [ メッセージ編集済み 編集者: 稍丼 編集日時 2007-01-12 16:24 ] | ||||
|
投稿日時: 2007-01-12 16:23
これと Control 派生かどうかは関係ないような?? | ||||
|
投稿日時: 2007-01-12 17:09
下の方の理由のところで,
finalizeメソッドは, UI thread からでなく,finalizer thread から呼ばれる。 STA で動いているCOMは,UI thread で作成されたので, UI threadからしか破棄できない。 だから,CLRは,抜け道を用意した。 とあったので,同じように, Window は,作成されたスレッドからしか破棄できない(できるのかな?)ので, NativeWindowをもつControlクラスでも同じことがいえるのかな... と勝手に思ったんですけどね。 なので,NativeWindowがウィンドウハンドルを握っている間は, GCされないようなシカケを入れたのかなと。 [追記] あらためて読み返してみると,抜け道の検証は, UI thread がビジー状態の時の検証をしないといけませんでした。 [ メッセージ編集済み 編集者: 稍丼 編集日時 2007-01-12 17:22 ] |