- PR -

Forms.Control継承型のファイナライゼーション

投稿者投稿内容
DSCH
常連さん
会議室デビュー日: 2005/10/23
投稿数: 24
投稿日時: 2007-01-03 18:44
掲題についての素朴な疑問です。

1.Finalizeメソッドの呼び出しはCLR内部の専用スレッドが行う。
2. Forms.Control派生型はそれを作成したスレッド以外から操作は保障されない。

この前提条件から
3. Forms.Control派生型のファイナライゼーションは保障されない
という結論が導き出せそうなのですが、
少し実験してみた限りではFinalizeメソッドの呼び出しは正常に行われているようにも思えます。

Forms.Control派生型のファイナライゼーションをしないといけない需要があるわけではありませんが、疑問に思ったので投稿させていただきました。
どなたかご存知の方はいらっしゃいますでしょうか?
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2007-01-03 21:06
引用:

DSCHさんの書き込み (2007-01-03 18:44) より:

3. Forms.Control派生型のファイナライゼーションは保障されない


それはないでしょう。

ところで、この "ファイナライゼーション" とは、Finalize メソッド自体のことなのでしょうか?
つまり、GC によって回収される s/保障/保証 がない、そういう意味なのでしょうか。

引用:

1.Finalizeメソッドの呼び出しはCLR内部の専用スレッドが行う。
2. Forms.Control派生型はそれを作成したスレッド以外から操作は保障されない。


これで、3 が真になってしまったら、ありとあらゆるすべてのコントロールが、
いかなる状況でも、ガベコレによって回収できないということになってしまいます。

ちなみに、Form が Close されると、Form 自身とその Form 内に含まれるすべてのコントロールに対して、
Dispose メソッドが呼び出されることになっています。
(これは、別スレッドから Close しても良いという意味ではありません)

このあと、任意のタイミングで GC が勝手に発動します。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-01-03 21:24
自動でファイナライズされること
と、
手動でファイナライズを行うこと

違いを知りたい、ってこと?
_________________
DSCH
常連さん
会議室デビュー日: 2005/10/23
投稿数: 24
投稿日時: 2007-01-03 21:39
じゃんぬねっとさん、返答ありがとうございます。

引用:

じゃんぬねっとさんの書き込み (2007-01-03 21:06) より:


ところで、この "ファイナライゼーション" とは、Finalize メソッド自体のことなのでしょうか?
つまり、GC によって回収される s/保障/保証 がない、そういう意味なのでしょうか。




あいまいな表現でしたね、すみません。
Finalizeメソッド内での処理自体という意味です。

引用:

これで、3 が真になってしまったら、ありとあらゆるすべてのコントロールが、
いかなる状況でも、ガベコレによって回収できないということになってしまいます。



Finalizeメソッドをオーバーライドしている型のオブジェクトの場合

1.最初のGCでファイナライズ待ちキュー(Fリーチャブルキュー)に入れられて、
2.専用スレッドからFinalizeメソッドが呼ばれて(仮に例外が発生しても専用用スレッドは握りつぶす)
3.次のGCでメモリから除去される

という流れでメモリ上から回収されるとには変わりないということですよね。

ちょっと実験してみたところでは、少なくとも例外は発生しませんした。
TextをいじってShow()してという無理やりなコードも表示までは動いたりもしました。
DSCH
常連さん
会議室デビュー日: 2005/10/23
投稿数: 24
投稿日時: 2007-01-03 21:45
引用:

Jittaさんの書き込み (2007-01-03 21:24) より:
自動でファイナライズされること
と、
手動でファイナライズを行うこと

違いを知りたい、ってこと?




コントロールを作成したしたスレッド以外のスレッドからのコントロールの操作は、
Invokeメソッドを利用してのみ可能とされていることから、
Finalize用スレッドによるFinalizeメソッドの呼び出しは問題ないのだろうか?
ということを知りたいということです。
DSCH
常連さん
会議室デビュー日: 2005/10/23
投稿数: 24
投稿日時: 2007-01-03 22:13
 
もしかすると、私は「他のスレッドから操作できない」の意を誤って解釈していたのかもしれません。

これは「CLR上でメソッドやプロパティにアクセスすること自体が問題」という意味ではなく、
「バックでコントロール関係のWindoesAPIを利用することになる場合、それらが正しく動く保証がない」という意味で

仮に自前のフォームクラスにコントロールと全く関係ない処理をするメソッドを定義したとすれば、そのメソッドは他のスレッドからの呼び出しても問題なく動作する。
Finalizeメソッドもメソッドの呼び出し自体は何の問題もなく、そのなかでどのような処理をするかが問題になる(このタイミングで描画関係の処理をするということは考えられませんね)。

こういうことだったりするのでしょうか?


[ メッセージ編集済み 編集者: DSCH 編集日時 2007-01-03 22:40 ]
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2007-01-04 12:36
面白い問題ですね。この問題を回避するためなのかどうかは分かりませんが、.NET Framework はいろいろ仕掛けを入れています。

Control が他スレッドからの操作による動作が保証されていないのは、ウィンドウハンドルが関連付けられているからです。つまり、そのコントロールがメッセージループによるメッセージ受信者だからです。

そして Control はウィンドウハンドルが関連付けられている限り、GC の対象になりません。
http://blogs.wankuma.com/shuujin/archive/2006/02/27/21562.aspx
http://blogs.wankuma.com/shuujin/archive/0001/01/01/22318.aspx

という事で、GC は必ずウィンドウハンドルが破棄された Control のみを掃除するので、GC は安全に Control を掃除する事ができます。
_________________
囚人のジレンマな日々
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-01-05 22:17
ここかな?
「マネージ コード パフォーマンスの向上」<microsoft.com>

_________________

スキルアップ/キャリアアップ(JOB@IT)