/// <summary> /// Gets the named thread context stack /// </summary> /// <value> /// The named stack /// </value> /// <remarks> /// <para> /// Gets the named thread context stack /// </para> /// </remarks> public LogicalThreadContextStack this[string key] { get { LogicalThreadContextStack logicalThreadContextStack = null; object obj = m_properties[key]; if (obj == null) { logicalThreadContextStack = new LogicalThreadContextStack(key, registerNew); m_properties[key] = logicalThreadContextStack; } else { logicalThreadContextStack = (obj as LogicalThreadContextStack); if (logicalThreadContextStack == null) { string text = SystemInfo.NullText; try { text = obj.ToString(); } catch { } LogLog.Error(declaringType, "ThreadContextStacks: Request for stack named [" + key + "] failed because a property with the same name exists which is a [" + obj.GetType().Name + "] with value [" + text + "]"); logicalThreadContextStack = new LogicalThreadContextStack(key, registerNew); } } return(logicalThreadContextStack); } }
/// <summary> /// Pushes a new context message into this stack. /// </summary> /// <param name="message">The new context message.</param> /// <returns> /// An <see cref="IDisposable"/> that can be used to clean up the context stack. /// </returns> /// <remarks> /// <para> /// Pushes a new context onto this stack. An <see cref="IDisposable"/> /// is returned that can be used to clean up this stack. This /// can be easily combined with the <c>using</c> keyword to scope the /// context. /// </para> /// </remarks> /// <example>Simple example of using the <c>Push</c> method with the <c>using</c> keyword. /// <code lang="C#"> /// using(log4net.LogicalThreadContext.Stacks["NDC"].Push("Stack_Message")) /// { /// log.Warn("This should have an ThreadContext Stack message"); /// } /// </code> /// </example> public IDisposable Push(string message) { // do modifications on a copy Stack stack = new Stack(new Stack(this.m_stack)); stack.Push(new StackFrame(message, (stack.Count > 0) ? (StackFrame)stack.Peek() : null)); LogicalThreadContextStack contextStack = new LogicalThreadContextStack(this.m_propertyKey, this.m_registerNew); contextStack.m_stack = stack; this.m_registerNew(this.m_propertyKey, contextStack); return(new AutoPopStackFrame(contextStack, stack.Count - 1)); }
/// <summary> /// Returns the stack to the correct depth. /// </summary> /// <remarks> /// <para> /// Returns the stack to the correct depth. /// </para> /// </remarks> public void Dispose() { if (m_frameDepth >= 0 && m_logicalThreadContextStack.m_stack != null) { Stack stack = new Stack(new Stack(m_logicalThreadContextStack.m_stack)); while (stack.Count > m_frameDepth) { stack.Pop(); } LogicalThreadContextStack ltcs = new LogicalThreadContextStack(m_logicalThreadContextStack.m_propertyKey, m_logicalThreadContextStack.m_registerNew); ltcs.m_stack = stack; m_logicalThreadContextStack.m_registerNew(m_logicalThreadContextStack.m_propertyKey, ltcs); } }
/// <summary> /// Removes the top context from this stack. /// </summary> /// <returns>The message in the context that was removed from the top of this stack.</returns> /// <remarks> /// <para> /// Remove the top context from this stack, and return /// it to the caller. If this stack is empty then an /// empty string (not <see langword="null"/>) is returned. /// </para> /// </remarks> public string Pop() { // copy current stack Stack stack = new Stack(new Stack(m_stack)); string result = ""; if (stack.Count > 0) { result = ((StackFrame)(stack.Pop())).Message; } LogicalThreadContextStack ltcs = new LogicalThreadContextStack(m_propertyKey, m_registerNew); ltcs.m_stack = stack; m_registerNew(m_propertyKey, ltcs); return(result); }
/// <summary> /// Gets the named thread context stack /// </summary> /// <value> /// The named stack /// </value> /// <remarks> /// <para> /// Gets the named thread context stack /// </para> /// </remarks> public LogicalThreadContextStack this[string key] { get { LogicalThreadContextStack stack = null; object propertyValue = m_properties[key]; if (propertyValue == null) { // Stack does not exist, create #if NET_2_0 || MONO_2_0 stack = new LogicalThreadContextStack(key, registerNew); #else stack = new LogicalThreadContextStack(key, new TwoArgAction(registerNew)); #endif m_properties[key] = stack; } else { // Look for existing stack stack = propertyValue as LogicalThreadContextStack; if (stack == null) { // Property is not set to a stack! string propertyValueString = SystemInfo.NullText; try { propertyValueString = propertyValue.ToString(); } catch { } LogLog.Error(declaringType, "ThreadContextStacks: Request for stack named [" + key + "] failed because a property with the same name exists which is a [" + propertyValue.GetType().Name + "] with value [" + propertyValueString + "]"); #if NET_2_0 || MONO_2_0 stack = new LogicalThreadContextStack(key, registerNew); #else stack = new LogicalThreadContextStack(key, new TwoArgAction(registerNew)); #endif } } return(stack); } }
/// <summary> /// Gets the named thread context stack /// </summary> /// <value> /// The named stack /// </value> /// <remarks> /// <para> /// Gets the named thread context stack /// </para> /// </remarks> public LogicalThreadContextStack this[string key] { get { LogicalThreadContextStack stack = null; object propertyValue = m_properties[key]; if (propertyValue == null) { // Stack does not exist, create #if NET_2_0 || MONO_2_0 stack = new LogicalThreadContextStack(key, registerNew); #else stack = new LogicalThreadContextStack(key, new TwoArgAction(registerNew)); #endif m_properties[key] = stack; } else { // Look for existing stack stack = propertyValue as LogicalThreadContextStack; if (stack == null) { // Property is not set to a stack! string propertyValueString = SystemInfo.NullText; try { propertyValueString = propertyValue.ToString(); } catch { } LogLog.Error(declaringType, "ThreadContextStacks: Request for stack named [" + key + "] failed because a property with the same name exists which is a [" + propertyValue.GetType().Name + "] with value [" + propertyValueString + "]"); #if NET_2_0 || MONO_2_0 stack = new LogicalThreadContextStack(key, registerNew); #else stack = new LogicalThreadContextStack(key, new TwoArgAction(registerNew)); #endif } } return stack; } }
private void registerNew(string stackName, LogicalThreadContextStack stack) { m_properties[stackName] = stack; }
/// <summary> /// Initializes a new instance of the <see cref="AutoPopStackFrame"/> struct. /// Constructor. /// </summary> /// <param name="logicalThreadContextStack">The internal stack used by the ThreadContextStack.</param> /// <param name="frameDepth">The depth to return the stack to when this object is disposed.</param> /// <remarks> /// <para> /// Initializes a new instance of the <see cref="AutoPopStackFrame" /> class with /// the specified stack and return depth. /// </para> /// </remarks> internal AutoPopStackFrame(LogicalThreadContextStack logicalThreadContextStack, int frameDepth) { this.m_frameDepth = frameDepth; this.m_logicalThreadContextStack = logicalThreadContextStack; }
/// <summary> /// Constructor /// </summary> /// <param name="logicalThreadContextStack">The internal stack used by the ThreadContextStack.</param> /// <param name="frameDepth">The depth to return the stack to when this object is disposed.</param> /// <remarks> /// <para> /// Initializes a new instance of the <see cref="AutoPopStackFrame" /> class with /// the specified stack and return depth. /// </para> /// </remarks> internal AutoPopStackFrame(LogicalThreadContextStack logicalThreadContextStack, int frameDepth) { m_frameDepth = frameDepth; m_logicalThreadContextStack = logicalThreadContextStack; }
/// <summary> /// Pushes a new context message into this stack. /// </summary> /// <param name="message">The new context message.</param> /// <returns> /// An <see cref="IDisposable"/> that can be used to clean up the context stack. /// </returns> /// <remarks> /// <para> /// Pushes a new context onto this stack. An <see cref="IDisposable"/> /// is returned that can be used to clean up this stack. This /// can be easily combined with the <c>using</c> keyword to scope the /// context. /// </para> /// </remarks> /// <example>Simple example of using the <c>Push</c> method with the <c>using</c> keyword. /// <code lang="C#"> /// using(log4net.LogicalThreadContext.Stacks["NDC"].Push("Stack_Message")) /// { /// log.Warn("This should have an ThreadContext Stack message"); /// } /// </code> /// </example> public IDisposable Push(string message) { // do modifications on a copy Stack stack = new Stack(new Stack(m_stack)); stack.Push(new StackFrame(message, (stack.Count > 0) ? (StackFrame)stack.Peek() : null)); LogicalThreadContextStack contextStack = new LogicalThreadContextStack(m_propertyKey, m_registerNew); contextStack.m_stack = stack; m_registerNew(m_propertyKey, contextStack); return new AutoPopStackFrame(contextStack, stack.Count - 1); }
/// <summary> /// Removes the top context from this stack. /// </summary> /// <returns>The message in the context that was removed from the top of this stack.</returns> /// <remarks> /// <para> /// Remove the top context from this stack, and return /// it to the caller. If this stack is empty then an /// empty string (not <see langword="null"/>) is returned. /// </para> /// </remarks> public string Pop() { // copy current stack Stack stack = new Stack(new Stack(m_stack)); string result = ""; if (stack.Count > 0) { result = ((StackFrame)(stack.Pop())).Message; } LogicalThreadContextStack ltcs = new LogicalThreadContextStack(m_propertyKey, m_registerNew); ltcs.m_stack = stack; m_registerNew(m_propertyKey, ltcs); return result; }