写入日志时C#锁定问题 [英] C# lock issues when writing to log
问题描述
我有一个使用Nlog框架以编程方式创建日志的类.我有几个同时运行的进程并创建它们的日志.我向类的构造函数添加了一个锁,就像在两个线程试图同时创建一个文件之前,这导致了一些令人讨厌的错误(例如仅创建一个日志).
这似乎已经解决了这个问题.但是现在我在写入日志时遇到了相同的问题,并且使用锁没有帮助.这是课程.
public class CwiLogger
{
private Logger _log;
private static Object createLogLock = new Object();
private static Object writeLogLock = new Object();
public CwiLogger(string logPath, string logName, string className)
{
lock (createLogLock)
{
var config = new LoggingConfiguration();
var fileTarget = new FileTarget();
config.AddTarget("file", fileTarget);
fileTarget.FileName = Path.Combine(logPath, logName);
fileTarget.Layout = "${longdate}|${level:uppercase=true}|${logger}|${message}";
var rule = new LoggingRule("*", LogLevel.Debug, fileTarget);
config.LoggingRules.Add(rule);
LogManager.Configuration = config;
this._log = LogManager.GetLogger(className);
}
}
public void AddToLog(string logText, LogLevel level = null)
{
lock (writeLogLock)
{
level = level ?? LogLevel.Info;
this._log.Log(level, logText + "\n");
}
}
}
在我的客户代码中,我运行两个线程,每个线程运行一个如下所示的进程:
var log = new CwiLogger(@"C:\Users\jma\Documents\ProgrammingJunk\logTest", "Log2.txt", "Log2");
for (int i = 0; i < 100; i++)
{
log.AddToLog("Log2 " + i);
}
仅我将log1用于一个,将log2用于另一个.
在我的输出中. 2个日志中的一个总是成功计数到99,而另一个获得4-5英寸,然后没有其他输出.也许是这样的:
public class CwiLogger
{
private static LoggingConfiguration _logConfig = new LoggingConfiguration();
private static Object createLogLock = new Object();
private Logger _log;
public CwiLogger(string logPath, string logName, string className)
{
lock (createLogLock)
{
var fileTarget = _logConfig.FindTargetByName(logName);
if (fileTarget == null)
{
var fileTarget = new FileTarget(logName);
fileTarget.FileName = Path.Combine(logPath, logName);
fileTarget.Layout = "${longdate}|${level:uppercase=true}|${logger}|${message}";
_logConfig.AddTarget(fileTarget);
var rule = new LoggingRule(className, LogLevel.Debug, fileTarget) { Final = true };
_logConfig.LoggingRules.Add(rule);
LogManager.Configuration = _logConfig;
}
}
this._log = LogManager.GetLogger(className);
}
public void AddToLog(string logText, LogLevel level = null)
{
level = level ?? LogLevel.Info;
this._log.Log(level, logText + "\n");
}
}
或者也许从这里窃取一些想法: https://github.com/NLog/NLog /issues/1998
I have a class that programmatically creates a log using the Nlog framework. I have several processes running and creating their logs at the same time. I added a lock to the constructor of the class, as before the two threads were attempting to create a file at the same time which resulted in some annoying bugs (like only creating one log).
This seems to have solved that problem. However now i have the same issue with writing to the log, and using a lock has not helped. Here is the class.
public class CwiLogger
{
private Logger _log;
private static Object createLogLock = new Object();
private static Object writeLogLock = new Object();
public CwiLogger(string logPath, string logName, string className)
{
lock (createLogLock)
{
var config = new LoggingConfiguration();
var fileTarget = new FileTarget();
config.AddTarget("file", fileTarget);
fileTarget.FileName = Path.Combine(logPath, logName);
fileTarget.Layout = "${longdate}|${level:uppercase=true}|${logger}|${message}";
var rule = new LoggingRule("*", LogLevel.Debug, fileTarget);
config.LoggingRules.Add(rule);
LogManager.Configuration = config;
this._log = LogManager.GetLogger(className);
}
}
public void AddToLog(string logText, LogLevel level = null)
{
lock (writeLogLock)
{
level = level ?? LogLevel.Info;
this._log.Log(level, logText + "\n");
}
}
}
In my client code i run two threads each running a process that looks like this:
var log = new CwiLogger(@"C:\Users\jma\Documents\ProgrammingJunk\logTest", "Log2.txt", "Log2");
for (int i = 0; i < 100; i++)
{
log.AddToLog("Log2 " + i);
}
only i use log1 for one and log2 for the other.
in my output. One of the 2 logs always sucessfully counts to 99, while the other gets 4-5 in and then has no other output.
Maybe something like this:
public class CwiLogger
{
private static LoggingConfiguration _logConfig = new LoggingConfiguration();
private static Object createLogLock = new Object();
private Logger _log;
public CwiLogger(string logPath, string logName, string className)
{
lock (createLogLock)
{
var fileTarget = _logConfig.FindTargetByName(logName);
if (fileTarget == null)
{
var fileTarget = new FileTarget(logName);
fileTarget.FileName = Path.Combine(logPath, logName);
fileTarget.Layout = "${longdate}|${level:uppercase=true}|${logger}|${message}";
_logConfig.AddTarget(fileTarget);
var rule = new LoggingRule(className, LogLevel.Debug, fileTarget) { Final = true };
_logConfig.LoggingRules.Add(rule);
LogManager.Configuration = _logConfig;
}
}
this._log = LogManager.GetLogger(className);
}
public void AddToLog(string logText, LogLevel level = null)
{
level = level ?? LogLevel.Info;
this._log.Log(level, logText + "\n");
}
}
Or maybe steal some ideas from here: https://github.com/NLog/NLog/issues/1998
这篇关于写入日志时C#锁定问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!