如何使静态类线程安全?

本文关键字:安全 线程 静态类 何使 | 更新日期: 2023-09-27 18:13:18

我有一个简单的静态日志类。但是,它绝对不是线程安全的,因为每个调用都试图写入同一个文件。我得到这些异常:

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(),我认为这违背了静态函数的目的。或者事实并非如此?

如何使静态类线程安全?

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);
        }
    }
}

在你的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);
    }
}