System.Drawingオブジェクトの破棄
-
05-07-2019 - |
質問
System.Drawingオブジェクトの有効期間を手動で管理する必要がありますか?
現在、「using」ステートメントを使用して、ブラシやその他の描画オブジェクトの寿命を最短にします。例:
using ( Brush br = new SolidBrush( color ) )
{
// Do something with br
}
これは必要ですか、または必要なときに必要な場合にガベージコレクターに魔法をかけることは安全ですか?
質問をさておき、...これを達成する最もクリーンな方法は何だと思いますか?
解決
System.Drawingオブジェクトを破棄するのは良いですが、例外などが発生したときに1つまたは2つを見逃しても、それは終わりではありません。 (開かれたファイルやデータベース接続などのその他のオブジェクトは、必ず破棄する必要があります)
多くの“使用中”コード全体のステートメントは、理解をより複雑にします。したがって、System.Drawingオブジェクトの場合は、メソッドの最後でDispose()を呼び出すだけで考慮します。
過去には、IDisposableを実装し、破棄するオブジェクトのコレクションを含む“ Dustcart”と記述したクラスを使用しました。その後、次のようなコードを記述できます。
using(var dustcart = new Dustcard())
{
var p = dustcart.Add(new Pen(red, etc));
var b = dustcart.Add(new Brush(black));
Pen t;
if (someFlag)
{
t = p;
}
else
{
t = dustcard.Add(new Pen(etc));
}
}
他のヒント
オブジェクトがIDisposableの場合、不要になったらすぐに破棄することをお勧めします。 (理由のためにIDisposableを実装しています)。
オフコース、Disposeの呼び出しを忘れると、ガベージコレクターはいつか作業を行い、クリーンアップするため、リソースは解放されますが、ガベージコレクターがいつ作動するかはわかりません。確定的ではありません。
だから、私のアドバイスは次のとおりです。使い捨てオブジェクトが不要になったらすぐに手動でDisposeを呼び出します(今やっているように)。
一般的な経験則では、オブジェクトがIDisposableを実装している場合は、クリーンアップする必要があります。 IDisposableは、.NET Frameworkの気まぐれには実装されていません-そこにあるのには十分な理由があります。
他の人が言ったように、IDisposableオブジェクトを作成したら、できるだけ早く破棄する必要があります。具体的な例では、コンパイル時に色がわかっている場合、Brush br = Brushes.Blueなどの標準ブラシを使用できますが、これは破棄する必要はありません。
同じ色を何度も繰り返し使用する場合、ブラシをクラスレベルのメンバーとして保存できますが、これは所有クラスもIDisposableであり、そのブラシメンバーをそのdisposeメソッドに配置することを意味します。 これにより、メモリストレージは(1つのブラシのサイズだけ)増加しますが、コードの量は減少する可能性があります(ステートメントを使用せず、追加のDisposeオーバーライド)。
筆者が質問で説明したように、「using」ステートメントを使用して、ブラシ、ペン、フォントなどのリソースが適切に廃棄されることを保証しています。私のコードでは、明示的な.Dispose()呼び出しが全体に散らばっているよりも、usingステートメントのほうがきれいです。しかし、それは私の好みです。
しかし、上記の答えには同意します。文または.Dispose呼び出しを使用するかどうかに関係なく、ガベージコレクターに依存するのではなく、リソースを手動でクリーンアップすることが非常に重要です。 (最初はガベージコレクターに依存していましたが、アプリの問題が複雑になる前からパフォーマンスの問題が表面化し始めていました。)