- - PR -
COM参照を確実に解放するコードの可読性をあげたい
投稿者 | 投稿内容 | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2006-03-16 11:25
なぬ!確かにファイナライザでは「いつ」という問題はありますが、という事は、マネージコードで増加させた参照カウントは、アプリケーション終了時には参照カウンタは全て減らすという事ですね。
それは頭が痛いですね。それって、自分達で管理して ReleaseComObject で減らそうと思っても、いつ減らせばいいのか分からないのではないですか? _________________ 囚人のジレンマな日々 | ||||||||||||||||
|
投稿日時: 2006-03-16 11:53
私への返信も似たようなものなんで、話が進んでいるこちらにぶら下げます。
昨日、どこかにも書きましたが「正常終了時に限り」ですね。 それと、既にリークしている場合がないとも限らなかったり。 ↑"そういう" 意味でも自前で参照を取って、責任を持ってしかるべき順番で、 ReleaseComObject していくというのが現状最も安全であると思います。
自分達が CLR なのか我々を指すのかで変わりますが、 使い終わって不要になったら即解放という現状のコーディング スタイルがそれでしょう。 IDisposable.Dispose ということであれば、 Dispose メソッド専用の「別の参照」を取っておき、すべてデクリメントするとか。(;^-^) ただ、そのラッパークラスのメンバに別の COM へ辿るルートがあると、 "大外で" ラップするだけでは意味がなくなってきます。 _________________ C# と VB.NET の入門サイト じゃんぬねっと日誌 | ||||||||||||||||
|
投稿日時: 2006-03-16 12:07
減らさなければならないです。
だから、何でもかんでも ReleaseCOMObject() すればいい、という訳ではないんです。 タイミングは非常に重要です。 前にも書きましたが、マネージラッパが内包している COM オブジェクトの参照を別の COM オブジェクトに渡せば、そこで COM オブジェクトの参照カウントは1増加します。 なので、闇雲に ReleaseCOMObiect() を実行すると、「別の COM オブジェクトが参照を保持しているかもしれない COM オブジェクト」のインスタンスを強制的に解放してしまうことにな兼ねません。 厳密に言えば「COM オブジェクトの参照を別の COM オブジェクトに渡した」のは、それを認識していようがいまいが、プログラマの書いたコードに基づいた振る舞いなのです。 なので、帳尻が合うように整合を保つのもプログラマの責任ということになります。 これは COM の大原則で、C++ でプログラミングしていても同じことが言えます。 _________________ // 渋木宏明 (Hiroaki SHIBUKI) // http://hidori.jp/ // Microsoft MVP for Visual C# [ メッセージ編集済み 編集者: 渋木宏明(ひどり) 編集日時 2006-03-16 12:29 ] | ||||||||||||||||
|
投稿日時: 2006-03-16 12:22
常にそうであるわけではないですよ。 別のスコープで参照を持っているものがいれば「1 個だけ」減らすという動作をします。 それ以外の場合では、すべてデクリメントされます。 # ひどりさんと COM Interop 関係の話をするのは何回目かなぁ (^^) _________________ C# と VB.NET の入門サイト じゃんぬねっと日誌 | ||||||||||||||||
|
投稿日時: 2006-03-16 12:32
返信元の記事の意味を取り違えてたんで、↑の記述はカットしてしまいました (^^;
もう飽きてきた (^^; _________________ // 渋木宏明 (Hiroaki SHIBUKI) // http://hidori.jp/ // Microsoft MVP for Visual C# // // @IT会議室 RSS 配信中: http://hidori.jp/rss/atmarkIT/ | ||||||||||||||||
|
投稿日時: 2006-03-16 13:12
何かいい方法ないかなぁと思いましたが、ひどりさんの言う COM 側へ渡す問題が存在するなら、そんないい方法はないんですね。
という事で納得。 COM Interop、少し突っ込んで調べてみようと思いました。
すいません。^^; _________________ 囚人のジレンマな日々 | ||||||||||||||||
|
投稿日時: 2006-03-16 15:44
南部です。
結局、単純なデクリメントは既にRCWで実装されているので、 参照をデクリメントする順番を考慮する場合や、 COMオブジェクトの有効期間を明示的に制御する場合以外は、 Marshal.ReleaseComObjectを叩く必要ない、、でいいのかな? #まあ、RCWのカウンタ下げるだけだし、デストラクタに任せても、、 例になった単純なケースでは、こんな感じ。
もし失念していなければ、これのソースを教えて欲しいのですが。 | ||||||||||||||||
|
投稿日時: 2006-03-16 16:59
GC によっていつ解放されるかわからないということは、 異常終了時にはリークしたままになるということを示します。 なので「有効期間を明示的に制御する場合以外」のシナリオがあまり思いつかなかったり... (;^-^) ユーザーに「はい、どうぞ」という意味であっても必須になるということです。 VB.NET から EXCELオブジェクトの操作
わーないです、というより多分間違ってます。 1 個というよりは未到達の分、デクリメントしようとする。 1 個でも有効な参照がある場合は、まったくデクリメントされない。 1 個だけという状況はない、が正しいかな。 _________________ C# と VB.NET の入門サイト じゃんぬねっと日誌 |