6

静的な単純な単純なロギング クラスがあります。ただし、すべての呼び出しが同じファイルに書き込もうとするため、スレッドセーフではありません。私はこれらの例外を受け取ります:

The process cannot access the file 'logfile.txt' because it is being used by another process.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) 
...

スレッドセーフにする最良の方法は何ですか?

public static class Logger
{
    private static readonly string LOG_FILENAME = "logfile.txt";
    private static readonly string LOG_FOLDER = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "App name");
    private static readonly string LOG_FULLPATH = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "App name", LOG_FILENAME);

    public static void LogMessageToFile(string msg)
    {
        msg = string.Format("{0:G}: {1}{2}", DateTime.Now, msg, Environment.NewLine);
        File.AppendAllText(LOG_FULLPATH, msg);
    }
}

ロギング機能として、コードのさまざまな部分からアクセスできるようにしたいと考えています (したがって、静的にすることを選択した理由)。ただし、スレッドセーフにするためには、lock() に共通のオブジェクトを常に渡す必要があると想像しています。これは、静的関数の目的を無効にしていると思います。それともそうではありませんか?

4

2 に答える 2

22
public static class Logger
{
    private static readonly string LOG_FILENAME = "logfile.txt";
    private static readonly string LOG_FOLDER = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "App name");
    private static readonly string LOG_FULLPATH = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "App name", LOG_FILENAME);

    private static Object theLock=new Object();

    public static void LogMessageToFile(string msg)
    {
        msg = string.Format("{0:G}: {1}{2}", DateTime.Now, msg, Environment.NewLine);
        lock (theLock)
        {
            File.AppendAllText(LOG_FULLPATH, msg);
        }
    }
}
于 2013-05-14T00:33:41.323 に答える
2

LogMessageToFile メソッドでは、マルチスレッド アクセスを防ぐためにロックが必要です。

private static Object _mylock = new Object();
public static void LogMessageToFile(string msg)
{
    lock(_mylock)
    {
       msg = string.Format("{0:G}: {1}{2}", DateTime.Now, msg, Environment.NewLine);
       File.AppendAllText(LOG_FULLPATH, msg);
    }
}
于 2013-05-14T00:33:05.727 に答える