/// <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);
        }
            /// <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;

                    // 每次 Pop() 后,用新的栈,将原来的替换掉
                    m_logicalThreadContextStack.m_registerNew(m_logicalThreadContextStack.m_propertyKey,
                                                              ltcs);
                }
            }
Ejemplo n.º 4
0
        /// <summary>
        /// 线程栈索引器
        /// 只读,如果键没找到,会自动添加一个键,然后返回一个空栈
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public LogicalThreadContextStack this[string key]
        {
            get
            {
                LogicalThreadContextStack stack = null;

                object propertyValue = m_properties[key];
                if (propertyValue == null)
                {
                    // Stack does not exist, create
                    stack             = new LogicalThreadContextStack(key, new TwoArgAction(registerNew));
                    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 + "]");

                        stack = new LogicalThreadContextStack(key, new TwoArgAction(registerNew));
                    }
                }

                return(stack);
            }
        }
 /// <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;
 }
Ejemplo n.º 6
0
 /// <summary>
 /// 在属性字典中,添加一个新的键值对或者将旧值覆盖掉
 /// </summary>
 /// <param name="stackName"></param>
 /// <param name="stack"></param>
 private void registerNew(string stackName, LogicalThreadContextStack stack)
 {
     m_properties[stackName] = stack;
 }