shuhelohelo’s blog

Xamarin.Forms多めです.

C# 非管理リソースの開放 (一時ファイル作成後の後始末について)

リソースの開放はIDisposableインターフェースを実装して,開放処理を記述します.

これについては以下の記事がとてもわかり易いです.

ufcpp.net

さて,この記事では「非管理リソースの開放」について書きます.

例えば,Path.GetTempFileName()メソッドで一時ファイルを作成したとします.

このメソッドはサイズ0バイトとのファイルを(Windowsでは)C:\Users\{User name}\AppData\Local\Tempフォルダ内に生成します. この一時ファイルに保存したいデータを書き込んだりして使います.

この一時ファイルですが,アプリケーションの終了時に自動的に削除されるわけではなく,残り続けます. ですので,利用し終わったら適切に削除する必要があります.

この一時ファイルは.NET Frameworkの管理外のため,非管理リソースとなります. このような非管理リソースを開放するには,一例として以下のようにすることができます.

一時ファイルを生成するためのクラスを作成し,このクラスにIDisposableを実装して,非管理リソースである一時ファイルが削除されるようにしています.

    public class TemporaryFile : IDisposable
    {
        private string fullName = Path.GetTempFileName();
        private bool disposedValue = false;

        public string FullName
        {
            get => fullName;
        }

        public void Dispose()
        {
            //GC前にプログラム的にリソースを破棄するので
            //管理,非管理リソース両方が破棄されるようにする
            Dispose(true);
            GC.SuppressFinalize(this);//破棄処理は完了しているのでGC不要の合図
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposedValue)
            {
                return;
            }

            if (disposing)
            {
                //管理リソースの破棄処理
            }

            //非管理リソースの破棄処理
            try
            {
                File.Delete(this.fullName);
            }
            catch
            {
                throw;
            }

            disposedValue = true;
        }

        ~TemporaryFile()
        {
            //GC時に実行されるデストラクタでは非管理リソースの削除のみ
            Dispose(false);
        }
    }

ここで使用しているのが,Disposeパターンです.

shuhelohelo.hatenablog.com

使い方

   using (var tempFile = new TemporaryFile())
    {
        File.WriteAllText(tempFile.FullName,"hello");
        //....
    }

using句を抜けるときにtempFileオブジェクトがDisposeされ,その際に一時ファイルがDeleteされます.