我在代码中使用 MemoryTarget Logger,它将从另一个线程提供。
有时,我需要向某些 webapi 调用提供日志,因此我需要检索 Logs 属性的内容。
问题是,Logs 属性是一个由 List 支持的 IList。因此,在写入日志时,可以通过 NLog 的帮助保持线程安全。在写入日志时,我无法访问日志的内容,并且我无法控制人们写入日志的时间和位置,而且似乎没有线程安全的选项来检索数据。
我正在使用 .Net 4.8 框架。
当前简化代码
public const string filter = "theFilterHere";
public string TargetName { get; set; }
public MemoryTarget Logger { get; private set; }
public void InitLog() {
Logger = new MemoryTarget();
var rule = new LoggingRule(filter, LogLevel.Debug, Logger);
LogManager.Configuration.AddTarget(TargetName, Logger);
LogManager.Configuration.LoggingRules.Add(rule);
LogManager.ReconfigExistingLoggers();
}
public List<string> Logs {
// Crash happens here. I need the list in reverse order because reasons, but looking at it I know I would have the same problem if I did a ToList first.
return Logger.Logs.Reverse().ToList();
}
我知道使用日志的 SyncRoot 不会有帮助,因为我不锁定对日志的写入访问权限。我今天唯一的想法是将日志(IList)转换为列表,然后执行类似于以下的代码:
List<string> currentLogs = Logger.Logs as List<string>;
if (currentLogs is null) {
// NLog changed the internal structure of MemoryTarget.
return Logger.Logs.Reverse().ToList();
}
int count = currentLogs.Count;
string[] logs = new string[count];
// Assumption : the list doesn't shrink, the log will only grow and never empty.
// this is only available on List<T>, and internally seems to do an Array copy of the _items array.
currentLogs.CopyTo(0, logs, 0, count);
我走在正确的道路上还是完全错了?
NLog v5.2.6 已发布,允许对 NLog 进行线程安全枚举 MemoryTarget
Logs
-属性: