問題タブ [idisposable]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
.net - ガベージコレクターはIDisposableを呼び出しますか?
.NET IDisposableパターン は、ファイナライザーを作成し、IDisposableを実装する場合、ファイナライザーが明示的にDisposeを呼び出す必要があることを意味します。これは論理的であり、ファイナライザーが必要とされるまれな状況で私が常に行ってきたことです。
ただし、これを実行するとどうなりますか。
ファイナライザーなどを実装しないでください。フレームワークはDisposeメソッドを呼び出しますか?
はい、私はこれがばかげているように聞こえることを理解しています、そしてすべての論理はそれがそうではないことを意味します、しかし私はいつも頭の後ろに2つのものを持っていました。
数年前の誰かが、実際にはそうするだろうと私に言ったことがあり、その人は「自分のことを知っている」という非常に確かな実績を持っていました。
コンパイラ/フレームワークは、実装するインターフェイスに応じて他の「魔法」のことを実行します(たとえば、foreach、拡張メソッド、属性に基づくシリアル化など)。したがって、これも「魔法」である可能性があります。
私はそれについて多くのことを読み、多くのことが暗示されてきましたが、この質問に対する決定的な「はい」または「いいえ」の答えを見つけることができませんでした。
c# - C#でC++スタイルのデストラクタを実行するには?
Dispose
経由の関数を持つ C# クラスがありますIDisposable
。ブロック内で使用することを意図しているusing
ため、処理する高価なリソースをすぐに解放できます。
問題は、 が呼び出される前に例外がスローされたときにバグが発生し、プログラマーがorDispose
の使用を怠ったことです。using
finally
C++ では、これについて心配する必要はありませんでした。クラスのデストラクタへの呼び出しは、オブジェクトのスコープの最後に自動的に挿入されます。そのような事態を回避する唯一の方法は、 new 演算子を使用してオブジェクトをポインターの背後に保持することですが、プログラマーにとって余分な作業が必要になるのは、using
.
using
ブロックをC#で自動的に使用する方法はありますか?
どうもありがとう。
アップデート:
ファイナライザーの回答を受け入れない理由を説明したいと思います。これらの答えは技術的には正しいですが、C++ スタイルのデストラクタではありません。
これが私が見つけたバグであり、本質的なものに縮小されています...
使用FXCop
することは素晴らしい提案ですが、それが私の唯一の答えである場合、私の質問は C# の人々への嘆願になるか、C++ を使用する必要があります。ネストされた 20 の using ステートメントはありますか?
c# - 派生クラスから自動的に base.Dispose() を呼び出す
編集 - 新しい質問
わかりました、質問をより一般的に言い換えましょう。
リフレクションを使用して、オーバーライドしている可能性のある基本クラス メソッドを実行時に動的に呼び出す方法はありますか。'base' キーワードが存在することを確認できないため、コンパイル時には使用できません。実行時に祖先のメソッドを一覧表示し、祖先のメソッドを呼び出したいと思います。
GetMethods() などを使用してみましたが、返されるのはメソッドの最も派生した実装への「ポインター」だけです。基本クラスでの実装ではありません。
バックグラウンド
比較的大きなクラス階層を持つ C# 3.0 でシステムを開発しています。これらのクラスの一部は、階層内の任意の場所に、破棄する必要のあるリソースがあり、それらはIDisposableインターフェイスを実装しています。
問題
ここで、コードのメンテナンスとリファクタリングを容易にするために、IDisposable を実装するクラスについて、先祖も IDisposable を実装している場合にbase.Dispose(bDisposing)を「自動的に」呼び出す方法を見つけたいと思います。このようにして、階層の上位にあるクラスが IDisposable の実装を開始または停止した場合、自動的に処理されます。
問題は二重です。
- まず、先祖が IDisposable を実装しているかどうかを調べます。
- 次に、base.Dispose(bDisposing) を条件付きで呼び出します。
最初の部分では、先祖が IDisposable を実装していることを発見し、対処することができました。
2番目の部分はトリッキーです。すべての努力にもかかわらず、派生クラスから base.Dispose(bDisposing) を呼び出すことができませんでした。私の試みはすべて失敗しました。それらはコンパイル エラーを引き起こしたか、最も派生したメソッドである間違った Dispose() メソッドを呼び出したため、永遠にループしていました。
主な問題は、 base.Dispose()を実装する先祖などがない場合、コード内で直接base.Dispose() を実際に参照できないことです ( IDisposable をまだ実装している祖先がない可能性があることを思い出してください。ただし、派生コードを将来そのようなことが起こった場合に備えてください)。これでリフレクションメカニズムが残りましたが、それを行う適切な方法が見つかりませんでした。私たちのコードは高度なリフレクション テクニックでいっぱいで、明らかな見落としはなかったと思います。
私の解決策
私の最善の策は、コメント付きのコードで使用する条件付きコードをいくつか用意することでした。IDisposable 階層を変更すると、ビルドが中断されるか (IDisposable の祖先が存在しない場合)、例外がスローされます (IDisposable の祖先が存在するが base.Dispose が呼び出されない場合)。
Dispose(bDisposing) メソッドがどのように見えるかを示すために投稿しているコードを次に示します。このコードを、階層全体のすべての Dispose() メソッドの最後に配置しています。新しいクラスは、このコードも含むテンプレートから作成されます。
だから、代わりに base.Dispose() を自動的に/条件付きで呼び出す方法はありますか?
その他の背景
アプリケーションには、すべてのオブジェクトがメイン クラスに登録される別のメカニズムがあります。クラスは、IDisposable を実装しているかどうかを確認します。その場合、それらはアプリケーションによって適切に破棄されます。これにより、コードがクラスを使用して Dispose() の呼び出しを処理する必要がなくなります。したがって、IDisposable の先祖の履歴がないクラスに IDisposable を追加しても、完全に機能します。
vb.net - VB.NET - IDisposable を実装するときに Finalize メソッドを追加する必要がありますか?
Visual Studio で " Implements IDisposable
" という行を入力すると、IDE によって次のものが自動的に追加されます。
- メンバー
disposedValue
変数 - a
Sub Dispose() Implements IDisposable.Dispose
- a
Sub Dispose(ByVal disposing As Boolean)
はそのDispose()
ままにして、クリーンアップ コードを に配置する必要がありますDispose(disposing)
。
ただし、Dispose Finalize パターンSub Finalize()
は、 callをオーバーライドする必要があることも示していますDispose(False)
。なぜIDEもこれを追加しないのですか? 自分で追加する必要がありますか、それとも何らかの方法で暗黙的に呼び出されますか?
編集: IDE が必要なものの 80% を自動的に追加するのに、Finalize メソッドを省略している理由がわかりませんか? この種の機能の要点は、これらのことを忘れないようにすることではないでしょうか?
EDIT2:素晴らしい回答をありがとうございました。これは完全に理にかなっています!
c# - ファイナライザーと破棄
BackgroundWorker
スレッドが常に実行されているという名前のクラスがあります。このスレッドをオフにするには、 to という名前のインスタンス変数がstop
である必要がありますtrue
。
クラスの使用が終了したときにスレッドが確実に解放されるようにするために、IDisposable
を呼び出すファイナライザーを追加しましたDispose()
。それが実際にこのスレッドを終了させると仮定するとstop = true
、このシペットは正しいですか? ファイナライザーから呼び出しDispose
てもいいですよね?
継承するDispose
場合、ファイナライザーは常に呼び出す必要がありますよね?object
IDisposable
c# - GC.SuppressFinalize()はいつ使用する必要がありますか?
.NETでは、どのような状況で使用する必要がありますGC.SuppressFinalize()
か?
この方法を使用するとどのような利点がありますか?
c# - IDisposable オブジェクト参照が破棄されているかどうかは、どのようにわかりますか?
参照が破棄されたオブジェクトへの参照であるかどうかを確認する方法、またはその他の軽量な方法はありますか?
PS - これは単なる好奇心です (製品コードではなく、よく眠ってください)。はい、ObjectDisposedException
オブジェクトのメンバーにアクセスしようとすると をキャッチできることはわかっています。
c# - IDisposable.Dispose内で例外をインターセプトする
IDisposable.Dispose
メソッドには、例外がスローされているかどうかを判断する方法がありますか?
ステートメントで例外がスローされた場合、オブジェクトが破棄されusing
たときにそれについて知りたいです。IDisposable
c# - IDisposableを破棄するWinforms
dispose と IDisposable を正しく使用するための優れた記事やチュートリアルを持っている人はいますか? これをジュニア開発者に説明しようとしていて、追加の資料や例などを入手したかった.
.net - IDisposableを単体テストするには?
の周りのライブラリ コードに取り組んでいますIDisposable
。管理パス (経由using
) は簡単にテストできます。私はファイナライザーについて疑問に思っていますSystem.GC.Collect()
.ファイナライザーを強制的に実行するのに十分な呼び出しはありますか?