C#のプログラミングで気を付けないといけないのがメモリリークです。通常のシステム開発ではそれ程気にしなくても良いのですが画像処理等メモリを多く使う場合やWPFにおいてメモリリークは問題になってきます。
その対策方法としてモデルのベースに解放処理を組み込み、PGではUsingを使用し確実なメモリの解放を行うこととする。
下記にその内容を記述します。
Dispose中かを判断するフラグを用意する。
public abstract class BaseModel : IDisposable
{
protected bool IsDisposed { get; set; } = false;
}
{
protected bool IsDisposed { get; set; } = false;
}
継承するDisposeメソッドを定義します。
protected virtual void Dispose(bool disposing)
{
// 終了処理中でない時、下記処理を行う。
if (this.IsDisposed == false)
{
if (disposing == true)
{
// ガーベージコレクションを解放します。
// ※自分のみを解放します。(全てを解放すると処理がすごく重くなります。)
GC.SuppressFinalize(this);
}
this.Disposed = true;
}
{
// 終了処理中でない時、下記処理を行う。
if (this.IsDisposed == false)
{
if (disposing == true)
{
// ガーベージコレクションを解放します。
// ※自分のみを解放します。(全てを解放すると処理がすごく重くなります。)
GC.SuppressFinalize(this);
}
this.Disposed = true;
}
パブリックのDisposeメソッドを定義します。
public void Dispose()
{
// Dispose(引数:true)を呼び出します。
this.Dispose(true);
}
{
// Dispose(引数:true)を呼び出します。
this.Dispose(true);
}
ファイナライザを定義します。
~BaseModel()
{
// Dispose(引数:false)を呼び出します。
this.Dispose(false);
}
{
// Dispose(引数:false)を呼び出します。
this.Dispose(false);
}
継承モデル例
public class Test : BaseModel
{
protected override void Dispose(bool disposing)
{
// 終了処理でない時に処理を行う。
if (this.IsDisposed == false)
{
// 管理外のオブジェクトを解放する。
・・・
// ベースのDisposeを呼び出す。
base.Dispose(disposing);
}
}
}
{
protected override void Dispose(bool disposing)
{
// 終了処理でない時に処理を行う。
if (this.IsDisposed == false)
{
// 管理外のオブジェクトを解放する。
・・・
// ベースのDisposeを呼び出す。
base.Dispose(disposing);
}
}
}
使用例
public class Main
{
public Main()
{
// Usingで処理することで確実にメモリの解放を行える。
using (var model = new Test()
{
・・・
}
}
}
{
public Main()
{
// Usingで処理することで確実にメモリの解放を行える。
using (var model = new Test()
{
・・・
}
}
}