9

这是我的日志写入功能:

public static void WriteLog(string source, string message)
{
    string logFilePath = @"C:\LogFile\log.txt";
    using (StreamWriter sw = new StreamWriter(logFilePath, true))
    {
        sw.Write(source + ": :" + message);
    }
}

但是这段代码有时会导致我出现错误:

该进程无法访问该文件,因为它正被另一个进程使用

所以我修改了我的代码,这是我的新代码:

public static void WriteLog(string source, string message)
{
    object _lock = new object();
    lock (_lock)
    {
        string logFilePath = @"C:\LogFile\log.txt";
        using (StreamWriter sw = new StreamWriter(logFilePath, true))
        {
            sw.Write(source + ": :" + message);
        }
    }
}

虽然使用此代码后我没有收到错误消息。但是我仍然只是想知道这是否是使用锁来防止由于死锁引起的此类错误的正确方法,以及我使用锁的方式是否正确。

4

2 回答 2

26

您在第二个示例中使用 lock 无论如何都不会正常工作,因为您创建了一个新的锁定对象并每次都锁定它。

你真正想要的文件是这样的:

public static void WriteLog(string source, string message)
    {
        string logFilePath = @"C:\LogFile\log.txt";

        using (FileStream file = new FileStream(logFilePath,FileMode.Append,FileAccess.Write,FileShare.None)) 
        {
            StreamWriter writer = new StreamWriter(file);

            writer.write(source + ": : " + message);

            file.Flush();
            file.Close();
        }
    }

这应该在您写入时专门锁定文件,但一旦完成,就会正确关闭文件。

这并不能解决线程问题,因为两个线程仍然可能发生冲突。如果一个线程锁定文件,后续请求将失败。

要使用锁解决此问题,请将锁对象移动到所有线程都可以共享和锁定的静态对象,例如:

public static class Logger
{

    private static object locker = new object();

    public static void Log(string source, string message)
    {
        lock (locker) 
        {
            string logFilePath = @"C:\LogFile\log.txt";

            using (FileStream file = new FileStream(logFilePath,FileMode.Append,FileAccess.Write,FileShare.None)) 
            {
                StreamWriter writer = new StreamWriter(file);

                writer.write(source + ": : " + message);   
                writer.Flush();

                file.Close();
            }
        }
    }

}

这将导致后续线程等待,直到锁变得可用,然后再按最初预期写入文件。

请注意 Oded 的评论,但仍然适用于此方法。

于 2012-09-04T19:21:08.427 回答
2

使用log4netEnterprise Library 中的 Logging Application Block。这肯定会对您有所帮助,因为他们已经缓冲了对文件的写入。

您可以在 Internet 上找到大量示例。

于 2012-09-04T19:22:55.450 回答