lig*_*gos 13 c# silverlight nlog
我想关闭我的应用程序并写入任何挂起的日志消息.所以我LogManager.Flush()在关机过程中打电话.但是,我没有看到所有的消息写出来.相反,如果我等待几秒钟(使用Thread.Sleep()),我会看到消息.
检查后在GitHub上NLOG的代码,我找到AsyncTargetWrapper.FlushAsync()方法仅调度惰性写入器线程上写上下一批次的所有未决消息.它不是同步写日志消息.
这是预期的行为吗?我期望LogManager.Flush()是同步的,即:阻塞直到写入所有待处理的消息(或超过超时).
我在关机时使用的代码:
LogManager.Flush(ex => { }, TimeSpan.FromSeconds(15));
Run Code Online (Sandbox Code Playgroud)
然后是初始化Nlog的代码(这是一个Silverlight应用程序,所以我没有使用任何配置文件).
public static void InitialiseNLog(LogLevel forLevel)
{
var config = new LoggingConfiguration();
// Add targets.
// We need an async target wrapping a custom web service call back to the server.
var serverTarget = new RemoteServiceTarget();
var asyncWrapper = new AsyncTargetWrapper(serverTarget, 10000, AsyncTargetWrapperOverflowAction.Discard);
asyncWrapper.TimeToSleepBetweenBatches = (int)TimeSpan.FromSeconds(2).TotalMilliseconds;
asyncWrapper.BatchSize = 200;
// Add rules.
var rule = new LoggingRule("Company.Application.SilverlightApp.*", forLevel, asyncWrapper);
config.LoggingRules.Add(rule);
// Activate the configuration.
LogManager.Configuration = config;
LogManager.GlobalThreshold = forLevel;
}
Run Code Online (Sandbox Code Playgroud)
ligos的评论是正确的。AsyncTargetWrapper.CloseTarget()由于NLog 问题 134修改了该方法,其中嵌套BufferingTargetWrapper未在域卸载时刷新。
LogManager.Shutdown()确实强制AsyncTargetWrapper同步有效地刷新,但必须在之后使用它,LogManager.Flush()因为诸如 之类的目标BufferingTargetWrapper实际上并没有在关闭时刷新。设置可能更好,LogManager.Configuration = null因为这会执行一次刷新,然后一次命中关闭目标,并且下次需要使用配置时将重新加载配置(如果使用配置文件)。
我已经测试了两者,我选择了后者,因为我希望在我把事情做对之后我的日志记录备份并运行,但鉴于问题是在 Silverlight 中,我建议:
LogManager.Flush();
LogManager.Shutdown();
Run Code Online (Sandbox Code Playgroud)
编辑
LogManager在域卸载或进程退出时将配置设置为 null,因此除非运行旧的 NLog 版本,否则我们不应该看到这个问题。NLog 问题已于 2012 年 10 月修复。在没有显式关闭或将 config 设置为 null 的情况下进行了测试,可以确认调用LogManager.Flush()就足够了。
我通过编辑当前的 NLog 源代码实现了修复。
在 AsyncTargetWrapper.cs 中,将FlushAsync()方法更改为:
protected override void FlushAsync(AsyncContinuation asyncContinuation)
{
this.flushAllContinuation = asyncContinuation;
}
Run Code Online (Sandbox Code Playgroud)
到:
protected override void FlushAsync(AsyncContinuation asyncContinuation)
{
this.flushAllContinuation = asyncContinuation;
this.ProcessPendingEvents(null); // Added to make this flush synchronous.
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8188 次 |
| 最近记录: |