作者热门文章
- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
这是我的日志写入函数:
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);
}
}
但这段代码有时会导致我出错:
The process cannot access the file because it is being used by another process
所以我稍微修改了我的代码,这是我的新代码:
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);
}
}
}
虽然我在使用这段代码后没有收到错误。但是我仍然只是想知道这是否是使用锁来防止由于死锁导致的此类错误的正确方法,以及我使用锁的方法是否正确。
最佳答案
您在第二个示例中对锁的使用无论如何都无法正常工作,因为您创建了一个新的锁对象并每次都将其锁定。
你真正想要的文件明智的是这样的:
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 的评论,它仍然适用于此方法。
关于c# - 锁会阻止错误 "The process cannot access the file because it is being used by another process"吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12269935/
我是一名优秀的程序员,十分优秀!