在方法中更新 MDC
Update MDC in Method
假设您有使用映射诊断上下文的代码:
public string TransformTruTopsFABExport(string xmlFile) {
var xml = String.Empty;
using (NestedDiagnosticsContext.Push(Guid.NewGuid()))
using (MappedDiagnosticsLogicalContext.SetScoped("xmlFile", xmlFile))
using (MappedDiagnosticsLogicalContext.SetScoped("xml", xml))
{
try
{
Logger.Info("Transformation started.");
xml = Decorated.TransformTruTopsFABExport(xmlFile);
MappedDiagnosticsLogicalContext.Set("xml", xml); // Try to remove it
Logger.Debug("Transformation done.");
return xml;
}
finally
{
xml = null;
}
}
}
我如何更新变量 "xml" 并在不从新设置的情况下自动镜像 MDC 中的更新?
Using后会自动从栈中移除,不过好像是双码。我可以使用类似 c 指针的东西吗?
编辑:在你问之前,我已经尝试使用这样的 DataClass:
class Dataclass
{
public string xml { get; set; }
public override string ToString()
{
return xml;
}
}
class Logicclass
{
Logger logger = LogManager.GetLogger("Logicclass");
public void MyMethod()
{
var dc = new Dataclass();
using (MappedDiagnosticsLogicalContext.SetScoped("xml", dc))
{
try
{
logger.Info("before XML");
dc.xml = "xmlcode";
logger.Info("after XML");
}
catch (Exception ex)
{
logger.Error(ex, "ow noos!");
throw;
}
}
logger.Info("after using");
}
}
是的,它会更新它。但这不是我要找的答案。
编辑:
变量的最简单解决方案是不可变的,引用将不起作用,为此使用 StringBuilder 。更新 StringBuilder 对象很简单,这里是一个使用 StringBuilder 对象的对象引用和 MDLC 的工作解决方案(魔术在添加内容之前清除它):
public void MyMethod()
{
StringBuilder xml = new StringBuilder();
StringBuilder numbers = new StringBuilder();
StringBuilder booleans = new StringBuilder();
using (NestedDiagnosticsContext.Push(Guid.NewGuid()))
using (MappedDiagnosticsLogicalContext.SetScoped("xml", xml))
using (MappedDiagnosticsLogicalContext.SetScoped("numbers", numbers))
using (MappedDiagnosticsLogicalContext.SetScoped("booleans", booleans))
{
try {
logger.Info("Before XML change");
xml.Clear().Append("<?xml version=\"1.0\" encoding=\"utf-8\"?>..");
numbers.Clear().Append(20);
logger.Info("After XML change");
booleans.Clear().Append(true);
logger.Info("After Boolean change");
numbers.Clear().Append(100);
logger.Info("After number change");
xml.Clear().Append("no xml anymore");
logger.Info("After XML change");
}
catch (Exception ex)
{
logger.Error(ex, "ow noos!");
throw;
}
}
logger.Info("After using");
}
当然,对于 return 值,我会不切实际,因为您必须将其转换回来,但在大多数情况下,我是一个很好的解决方案,并且比再次设置 MDLC 更具可读性。
此致
Lord_Pinhead
MappedDiagnosticsLogicalContext.SetScoped
不会在处置时恢复任何原始值。它只是删除了处理时的活动值。
NET Framework 字符串对象是不可变的,无法修改。您可以考虑使用 StringBuilder(将表现得像您的 DataClass)。
假设您有使用映射诊断上下文的代码:
public string TransformTruTopsFABExport(string xmlFile) {
var xml = String.Empty;
using (NestedDiagnosticsContext.Push(Guid.NewGuid()))
using (MappedDiagnosticsLogicalContext.SetScoped("xmlFile", xmlFile))
using (MappedDiagnosticsLogicalContext.SetScoped("xml", xml))
{
try
{
Logger.Info("Transformation started.");
xml = Decorated.TransformTruTopsFABExport(xmlFile);
MappedDiagnosticsLogicalContext.Set("xml", xml); // Try to remove it
Logger.Debug("Transformation done.");
return xml;
}
finally
{
xml = null;
}
}
}
我如何更新变量 "xml" 并在不从新设置的情况下自动镜像 MDC 中的更新? Using后会自动从栈中移除,不过好像是双码。我可以使用类似 c 指针的东西吗?
编辑:在你问之前,我已经尝试使用这样的 DataClass:
class Dataclass
{
public string xml { get; set; }
public override string ToString()
{
return xml;
}
}
class Logicclass
{
Logger logger = LogManager.GetLogger("Logicclass");
public void MyMethod()
{
var dc = new Dataclass();
using (MappedDiagnosticsLogicalContext.SetScoped("xml", dc))
{
try
{
logger.Info("before XML");
dc.xml = "xmlcode";
logger.Info("after XML");
}
catch (Exception ex)
{
logger.Error(ex, "ow noos!");
throw;
}
}
logger.Info("after using");
}
}
是的,它会更新它。但这不是我要找的答案。
编辑: 变量的最简单解决方案是不可变的,引用将不起作用,为此使用 StringBuilder 。更新 StringBuilder 对象很简单,这里是一个使用 StringBuilder 对象的对象引用和 MDLC 的工作解决方案(魔术在添加内容之前清除它):
public void MyMethod()
{
StringBuilder xml = new StringBuilder();
StringBuilder numbers = new StringBuilder();
StringBuilder booleans = new StringBuilder();
using (NestedDiagnosticsContext.Push(Guid.NewGuid()))
using (MappedDiagnosticsLogicalContext.SetScoped("xml", xml))
using (MappedDiagnosticsLogicalContext.SetScoped("numbers", numbers))
using (MappedDiagnosticsLogicalContext.SetScoped("booleans", booleans))
{
try {
logger.Info("Before XML change");
xml.Clear().Append("<?xml version=\"1.0\" encoding=\"utf-8\"?>..");
numbers.Clear().Append(20);
logger.Info("After XML change");
booleans.Clear().Append(true);
logger.Info("After Boolean change");
numbers.Clear().Append(100);
logger.Info("After number change");
xml.Clear().Append("no xml anymore");
logger.Info("After XML change");
}
catch (Exception ex)
{
logger.Error(ex, "ow noos!");
throw;
}
}
logger.Info("After using");
}
当然,对于 return 值,我会不切实际,因为您必须将其转换回来,但在大多数情况下,我是一个很好的解决方案,并且比再次设置 MDLC 更具可读性。
此致 Lord_Pinhead
MappedDiagnosticsLogicalContext.SetScoped
不会在处置时恢复任何原始值。它只是删除了处理时的活动值。
NET Framework 字符串对象是不可变的,无法修改。您可以考虑使用 StringBuilder(将表现得像您的 DataClass)。