- PR -

VB.NET によるイベント ハンドラのについて

投稿者投稿内容
架空兎
ベテラン
会議室デビュー日: 2003/08/18
投稿数: 78
お住まい・勤務地: さいたま氏
投稿日時: 2004-02-13 01:48
引用:

なちゃさんの書き込み (2004-02-12 20:33) より:

えーここの辺りを確認するには、最終的に参照がルートにつながっているかを考える必要があります。
>AddHandler SampleProcess.Exited, AddressOf processExited
これにより、SampleProcessオブジェクトには、clsSampleへの参照が含まれていることになります。
したがって、SampleProcessオブジェクトが生きている(ここでは破棄されたという意味ではなく、参照が残っているという意味で)限り、clsSampleは生きていることになります。
では、SampleProcessオブジェクトの参照は誰が保持しているでしょうか?clsSample自身ですね。すなわち循環参照であり、ルートにつながっていないため、これ自体は意味を持ちません
では、clsSampleを誰か他の場所から参照しているでしょうか?
Button1_Clickメソッドが終了すると、もはや誰も参照していませんね。

さて、Button1_Clickメソッドが終了した後で、たまたまGCが発生したとします。

ここでGCは、ルートから全てのオブジェクトをたどって、オブジェクトが有効か調べます。どこからもSampleProcessおよびclsSampleにはたどり着きませんので、GCの対象になります。


# Process オブジェクトの内部の動作が分からないので何とも言えないのですが。。。^^;

もし、SampleProcess の内部で処理が実行中である(つまり、Process#Exited イベントを
発生させるために Process オブジェクトの内部でプロセスが終了するのを
待機している)とするなら、それ自身はまだ GC の対象にはなりません。
そして、clsSample オブジェクトは実行中である SampleProcess が参照しているため
clsSample オブジェクトもまだ GC の対象にはなりません。
では、いつ GC の対象になるのかというと SampleProcess の処理が終了したとき
(つまり、プロセスが終了した後)に初めて GC の対象になります。
もしくは、SampleProcess が Dispose された後です。
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2004-02-13 02:57
引用:

架空兎さんの書き込み (2004-02-13 01:48) より:
# Process オブジェクトの内部の動作が分からないので何とも言えないのですが。。。^^;


言い切ってしまいましたがこれはもちろんそのとおりで、例えば内部で静的なテーブルに実行中のプロセスが登録されでもしていれば、GC対象にはなりません。
まあ、言いたかったこととしてはまず、参照が存在していても、それがルートからつながっていなければGC対象になる事、たとえば相互に参照が存在(循環参照など)していても、GC対象になり得ると言う事です。
そしてもう一つは、内部の実装に依存しており特に保証されていない以上、例え実際には大丈夫であっても、それは現在の実装においてたまたま大丈夫だったにすぎない可能性もあり、そういった部分に依存するプログラムは避けた方がいいということです。

引用:

もし、SampleProcess の内部で処理が実行中である(つまり、Process#Exited イベントを
発生させるために Process オブジェクトの内部でプロセスが終了するのを
待機している)とするなら、それ自身はまだ GC の対象にはなりません。


確かに、実際には回りまわってGC対象にはならない状態になっているようです。
# EnableRasingEventsがFalseの場合は、GC対象になるようです。
ただ、Processのドキュメントを読んだ感じでは、OSのハンドルを使って終了を待機しているような感じなので、オブジェクトの内部で処理が実行中というのとは、また違うような気がします。
# 待機終了時のスレッドプールでのコールバックにデリゲートを使用しているため、
# 今度は待機用スレッドプール実装からProcessへの参照が生きているとか。
ま、実際のところは良く分かりませんです、はい。
Yun
会議室デビュー日: 2004/02/10
投稿数: 13
投稿日時: 2004-02-13 19:56
返信ありがとうございます

架空兎様
引用:

System.Windows.Forms.Timer クラスの代わりに
System.Timers.Timer クラスを使うという手も一応はあると思います。
#一応は大丈夫っぽいです。


確認して頂いきありがとうございます。
実は最初はSystem.Timers.Timer実装していたのですよ。
サンプルにする場合にSystem.Windows.Forms.Timerの方が
わかり易いと尾思いコントロールにしました。
System.Timers.Timerでも使えそうで安心しました。

なちゃ様
引用:

まあ、正直なところで言うと、「怪しい or 自信のないことはするな」ということで、私はやらないです…


確かに怪しいんですよね^^;
自分も経験則と結果から予想・・・妄想している状態ですから(汗
念の為、Form内のグローバル変数にすることにしました。

残念ながらGCやオブジェクトの参照系でこれだっ!って言う
参考文献がまだ見つかってないのが私の現状です。
たまに内部ルーチンを彼是考えて興に入ることが結構あったり(笑
実際に確認できるViewerがあると楽なのですが・・・
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-02-14 08:37
引用:

なっくさんの書き込み (2004-02-13 19:56) より:

サンプルにする場合にSystem.Windows.Forms.Timerの方が
わかり易いと思いコントロールにしました。
System.Timers.Timerでも使えそうで安心しました。


 他のスレッドにもありますが、System.Windows.Forms.Timerの精度は低いので、注意。Interval=1は、精度的に機能できません。サンプルならいいとも思いますが、「仕様通りに動かないサンプル」というのもなんですので。
Yun
会議室デビュー日: 2004/02/10
投稿数: 13
投稿日時: 2004-02-16 09:35
Jitta様 返信ありがとうござます

引用:

他のスレッドにもありますが、System.Windows.Forms.Timerの精度は低いので、注意。Interval=1は、精度的に機能できません。サンプルならいいとも思いますが、「仕様通りに動かないサンプル」というのもなんですので。



多分こちらのスレの事ですね
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=9054&forum=7

うをっ、予想以上に精度悪いですね・・・^^;
一寸、時間にシビアな部分があるのですが・・・
Windows.Forms.Timerは使わない方がよさそうですね。
助かりました。ありがとうございます><

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