如何使静态类线程安全?

Dou*_*oug 6 c# wpf logging static-methods thread-safety

我有一个简单的简单日志类,它是静态的.但是,它绝对不是线程安全的,因为每次调用都会尝试写入同一个文件.我得到以下例外:

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) 
...
Run Code Online (Sandbox Code Playgroud)

使线程安全的最佳方法是什么?

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

作为日志功能,我希望能够从我的代码的许多不同部分访问它(因此,为什么我选择它作为静态).但是,我想象的是为了使它成为线程安全的,我总是要将它传递给lock()on一个常见的对象,我认为这违背了静态函数的目的.或者不是这样吗?

Eug*_*eck 20

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • ...说明? (3认同)
  • `lock确保一个线程不进入代码的关键部分,而另一个线程在临界区.如果另一个线程试图输入锁定的代码,它将等待,阻止,直到该对象被释放 (3认同)