DiagnosticTrace.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / SMDiagnostics / System / ServiceModel / Diagnostics / DiagnosticTrace.cs / 2 / DiagnosticTrace.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

namespace System.ServiceModel.Diagnostics 
{
    using System.Diagnostics; 
    using System.ServiceModel; 
    using System.Xml.XPath;
    using System.Xml; 
    using System.Runtime.InteropServices;
    using System.Configuration;
    using System.Globalization;
    using System.Security.Principal; 
    using System.ServiceModel.Configuration;
    using System.Text; 
    using System.ComponentModel; 
    using System.Collections.Generic;
    using System.Reflection; 
    using System.Security;
    using System.Security.Permissions;

    class DiagnosticTrace 
    {
        const string DefaultTraceListenerName = "Default"; 
        const int MaxTraceSize = 65535; 
        bool tracingEnabled = true;
        bool haveListeners = false; 
        object localSyncObject = new object(); // only used by ShouldTrace, only used once.
        DateTime lastFailure = DateTime.MinValue;
        SourceLevels level;
        bool calledShutdown = false; 
        bool shouldUseActivity = false;
        string AppDomainFriendlyName = null; 
        PiiTraceSource traceSource = null; 
        TraceSourceKind traceSourceType = TraceSourceKind.PiiTraceSource;
        const string subType = ""; 
        const string version = "1";
        const int traceFailureLogThreshold = 1;
        string TraceSourceName = string.Empty;
        const string TraceRecordVersion = "http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord"; 
        const SourceLevels DefaultLevel = SourceLevels.Off;
        static SortedList traceCodes = new SortedList(); 
        static object classLockObject = new object(); 

        ///  
        /// Critical - This determines the event source name
        /// 
        [SecurityCritical]
        string eventSourceName = string.Empty; 

        internal static string ProcessName 
        { 
            get
            { 
                string retval = null;
                using (Process process = Process.GetCurrentProcess())
                {
                    retval = process.ProcessName; 
                }
                return retval; 
            } 
        }
 
        internal static int ProcessId
        {
            get
            { 
                int retval = -1;
                using (Process process = Process.GetCurrentProcess()) 
                { 
                    retval = process.Id;
                } 
                return retval;
            }
        }
 
        internal PiiTraceSource TraceSource
        { 
            get 
            {
                return this.traceSource; 
            }

            set
            { 
                this.traceSource = value;
            } 
        } 

        SourceLevels FixLevel(SourceLevels level) 
        {
            //the bit fixing below is meant to keep the trace level legal even if somebody uses numbers in config
            if (((level & ~SourceLevels.Information) & SourceLevels.Verbose) != 0)
            { 
                level |= SourceLevels.Verbose;
            } 
            else if (((level & ~SourceLevels.Warning) & SourceLevels.Information) != 0) 
            {
                level |= SourceLevels.Information; 
            }
            else if (((level & ~SourceLevels.Error) & SourceLevels.Warning) != 0)
            {
                level |= SourceLevels.Warning; 
            }
            if (((level & ~SourceLevels.Critical) & SourceLevels.Error) != 0) 
            { 
                level |= SourceLevels.Error;
            } 
            if ((level & SourceLevels.Critical) != 0)
            {
                level |= SourceLevels.Critical;
            } 

            // If only the ActivityTracing flag is set, then 
            // we really have Off. Do not do ActivityTracing then. 
            if (level == SourceLevels.ActivityTracing)
            { 
                level = SourceLevels.Off;
            }

            return level; 
        }
 
        void SetLevel(SourceLevels level) 
        {
            SourceLevels fixedLevel = FixLevel(level); 
            this.level = fixedLevel;

            if (this.TraceSource != null)
            { 
                // Need this for setup from places like TransactionBridge.
                this.haveListeners = this.TraceSource.Listeners.Count > 0; 
 
                if (this.TraceSource.Switch.Level != SourceLevels.Off &&
                    level == SourceLevels.Off) 
                {
                    TraceSource temp = this.TraceSource;
                    this.CreateTraceSource();
                    temp.Close(); 
                }
#pragma warning disable 618 
                this.tracingEnabled = this.HaveListeners && (fixedLevel != SourceLevels.Off); 
#pragma warning restore 618
                this.TraceSource.Switch.Level = fixedLevel; 
                this.shouldUseActivity = (fixedLevel & SourceLevels.ActivityTracing) != 0;
            }
        }
 
        void SetLevelThreadSafe(SourceLevels level)
        { 
            lock (this.localSyncObject) 
            {
                SetLevel(level); 
            }
        }

        [Obsolete("For SMDiagnostics.dll use only. Call DiagnosticUtility.Level instead")] 
        internal SourceLevels Level
        { 
            //Do not call this property from Initialize! 
            get
            { 
                if (this.TraceSource != null && (this.TraceSource.Switch.Level != this.level))
                {
                    this.level = this.TraceSource.Switch.Level;
                } 
                return this.level;
            } 
 
            set
            { 
                SetLevelThreadSafe(value);
            }
        }
 
        static internal string CodeToString(TraceCode code)
        { 
            string traceCodeString = null; 
            if (!DiagnosticTrace.traceCodes.TryGetValue(code, out traceCodeString))
            { 
                lock (classLockObject)
                {
                    if (!DiagnosticTrace.traceCodes.TryGetValue(code, out traceCodeString))
                    { 
                        traceCodeString = code.ToString();
                        DiagnosticTrace.traceCodes.Add(code, traceCodeString); 
                    } 
                }
            } 
            return traceCodeString;
        }

        static internal string GenerateTraceCode(TraceCode code) 
        {
            TraceCode group = (TraceCode)(((int)code) & 0xFFFF0000); 
            string terminatorUri = null; 
            switch (group)
            { 
                case TraceCode.Activation:
                    terminatorUri = "System.ServiceModel.Activation";
                    break;
                case TraceCode.Administration: 
                    terminatorUri = "System.ServiceModel.Administration";
                    break; 
                case TraceCode.Channels: 
                    terminatorUri = "System.ServiceModel.Channels";
                    break; 
                case TraceCode.ComIntegration:
                    terminatorUri = "System.ServiceModel.ComIntegration";
                    break;
                case TraceCode.Diagnostics: 
                    terminatorUri = "System.ServiceModel.Diagnostics";
                    break; 
                case TraceCode.IdentityModel: 
                    terminatorUri = "System.IdentityModel";
                    break; 
                case TraceCode.IdentityModelSelectors:
                    terminatorUri = "System.IdentityModel.Selectors";
                    break;
                case TraceCode.PortSharing: 
                    terminatorUri = "System.ServiceModel.PortSharing";
                    break; 
                case TraceCode.Security: 
                    terminatorUri = "System.ServiceModel.Security";
                    break; 
                case TraceCode.Serialization:
                    terminatorUri = "System.Runtime.Serialization";
                    break;
                case TraceCode.ServiceModel: 
                case TraceCode.ServiceModelTransaction:
                    terminatorUri = "System.ServiceModel"; 
                    break; 
                case TraceCode.TransactionBridge:
                    terminatorUri = "Microsoft.Transactions.TransactionBridge"; 
                    break;
                default:
                    terminatorUri = string.Empty;
                    break; 
            }
            return string.Format(CultureInfo.InvariantCulture, 
                "http://msdn.microsoft.com/{0}/library/{1}.{2}.aspx", 
                CultureInfo.CurrentCulture.Name,
                terminatorUri, 
                DiagnosticTrace.CodeToString(code));
        }

        [Obsolete("For SMDiagnostics.dll use only. Call DiagnosticUtility.HaveListeners instead")] 
        internal bool HaveListeners
        { 
            get 
            {
                return this.haveListeners; 
            }
        }

        [Obsolete("For SMDiagnostics.dll use only. Call DiagnosticUtility.ShouldTrace instead")] 
        internal bool ShouldTrace(TraceEventType type)
        { 
            return this.TracingEnabled && 
                (this.TraceSource != null) &&
                0 != ((int)type & (int)this.Level); 
        }

        [Obsolete("For SMDiagnostics.dll use only. Call DiagnosticUtility.ShouldUseActivity instead")]
        internal bool ShouldUseActivity 
        {
            get { return this.shouldUseActivity; } 
        } 

        [Obsolete("For SMDiagnostics.dll use only. Call DiagnosticUtility.TracingEnabled instead")] 
        internal bool TracingEnabled
        {
            get
            { 
                return this.tracingEnabled && this.traceSource != null;
            } 
        } 

#pragma warning disable 56500 
        [Obsolete("For SMDiagnostics.dll use only. Never 'new' this type up unless you are DiagnosticUtility.")]
        /// 
        /// Critical - Sets eventSourceName
        ///  
        [SecurityCritical]
        internal DiagnosticTrace(TraceSourceKind sourceType, string traceSourceName, string eventSourceName) 
        { 
            this.traceSourceType = sourceType;
            this.TraceSourceName = traceSourceName; 
            this.eventSourceName = eventSourceName;

            // We own the resource and it hasn't been filled in yet.
            //needed for logging events to event log 
            this.AppDomainFriendlyName = AppDomain.CurrentDomain.FriendlyName;
 
            try 
            {
                this.CreateTraceSource(); 
                this.UnsafeAddDomainEventHandlersForCleanup();
            }
            catch (ConfigurationErrorsException)
            { 
                throw;
            } 
            catch (Exception e) 
            {
                if (ExceptionUtility.IsFatal(e)) 
                {
                    throw;
                }
                EventLogger logger = new EventLogger(this.eventSourceName, null); 
                logger.LogEvent(TraceEventType.Error, EventLogCategory.Tracing, EventLogEventId.FailedToSetupTracing, false,
                    e.ToString()); 
            } 
        }
#pragma warning restore 56500 

        [SecurityCritical]
        [SecurityPermission(SecurityAction.Assert, UnmanagedCode = true)]
        [Obsolete("For SMDiagnostics.dll use only")] 
        void UnsafeAddDomainEventHandlersForCleanup()
        { 
            AppDomain currentDomain = AppDomain.CurrentDomain; 
            this.haveListeners = this.TraceSource.Listeners.Count > 0;
            this.tracingEnabled = this.HaveListeners; 
            if (this.TracingEnabled)
            {
                currentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler);
                this.SetLevel(this.TraceSource.Switch.Level); 
                currentDomain.DomainUnload += new EventHandler(ExitOrUnloadEventHandler);
                currentDomain.ProcessExit += new EventHandler(ExitOrUnloadEventHandler); 
            } 
        }
 
        [SecurityCritical]
        [SecurityPermission(SecurityAction.Assert, UnmanagedCode = true)]
        void UnsafeRemoveDefaultTraceListener(PiiTraceSource piiTraceSource)
        { 
            piiTraceSource.Listeners.Remove(DiagnosticTrace.DefaultTraceListenerName);
        } 
 
        [SecurityCritical, SecurityTreatAsSafe]
        void CreateTraceSource() 
        {
            PiiTraceSource tempSource = null;
            if (this.traceSourceType == TraceSourceKind.PiiTraceSource)
            { 
                tempSource = new PiiTraceSource(this.TraceSourceName, this.eventSourceName, DiagnosticTrace.DefaultLevel);
            } 
            else 
            {
                tempSource = new DiagnosticTraceSource(this.TraceSourceName, this.eventSourceName, DiagnosticTrace.DefaultLevel); 
            }

            UnsafeRemoveDefaultTraceListener(tempSource);
            this.TraceSource = tempSource; 
        }
 
#pragma warning disable 56500 
        internal void TraceEvent(TraceEventType type, TraceCode code, string description, TraceRecord trace, Exception exception, object source)
        { 
#pragma warning disable 618
            AssertUtility.DebugAssert(exception == null || type <= TraceEventType.Information, "Exceptions should be traced at Information or higher");
            AssertUtility.DebugAssert(!string.IsNullOrEmpty(description), "All TraceCodes should have a description");
#pragma warning restore 618 
            TraceXPathNavigator navigator = null;
            try 
            { 
#pragma warning disable 618
                if (this.TraceSource != null && this.HaveListeners) 
#pragma warning restore 618
                {
                    try
                    { 
                        BuildTrace(type, code, description, trace, exception, source, out navigator);
                    } 
                    catch (PlainXmlWriter.MaxSizeExceededException) 
                    {
                        StringTraceRecord codeTraceRecord = new StringTraceRecord("TruncatedTraceId", GenerateTraceCode(code)); 
                        this.TraceEvent(type, TraceCode.TraceTruncatedQuotaExceeded, TraceSR.GetString(TraceSR.TraceCodeTraceTruncatedQuotaExceeded), codeTraceRecord);
                    }
                    this.TraceSource.TraceData(type, (int)code, navigator);
                    if (this.calledShutdown) 
                    {
                        this.TraceSource.Flush(); 
                    } 
                    // Must have been a successful trace.
                    this.LastFailure = DateTime.MinValue; 
                }
            }
            catch (Exception e)
            { 
                if (ExceptionUtility.IsFatal(e))
                { 
                    throw; 
                }
                LogTraceFailure(navigator == null ? string.Empty : navigator.ToString(), e); 
            }
        }
#pragma warning restore 56500
 
        internal void TraceEvent(TraceEventType type, TraceCode code, string description)
        { 
            this.TraceEvent(type, code, description, null, null, null); 
        }
 
        internal void TraceEvent(TraceEventType type, TraceCode code, string description, TraceRecord trace)
        {
            this.TraceEvent(type, code, description, trace, null, null);
        } 

        internal void TraceEvent(TraceEventType type, TraceCode code, string description, TraceRecord trace, Exception exception) 
        { 
            this.TraceEvent(type, code, description, trace, exception, null);
        } 

        internal void TraceEvent(TraceEventType type, TraceCode code, string description, TraceRecord trace, Exception exception, Guid activityId, object source)
        {
#pragma warning disable 618 
            using (this.ShouldUseActivity && Guid.Empty == activityId ? null : Activity.CreateActivity(activityId))
#pragma warning restore 618 
            { 
                this.TraceEvent(type, code, description, trace, exception, source);
            } 
        }


#pragma warning disable 56500 
        internal void TraceTransfer(Guid newId)
        { 
#pragma warning disable 618 
            if (this.ShouldUseActivity)
#pragma warning restore 618 
            {
                Guid oldId = DiagnosticTrace.ActivityId;
                if (newId != oldId)
                { 
#pragma warning disable 618
                    if (this.HaveListeners) 
#pragma warning restore 618 
                    {
                        try 
                        {
                            this.TraceSource.TraceTransfer(0, null, newId);
                        }
                        catch (Exception e) 
                        {
                            if (ExceptionUtility.IsFatal(e)) 
                            { 
                                throw;
                            } 
                            LogTraceFailure(null, e);
                        }
                    }
                } 
            }
        } 
#pragma warning restore 56500 

        static internal string CreateSourceString(object source) 
        {
            return source.GetType().ToString() + "/" + source.GetHashCode().ToString(CultureInfo.CurrentCulture);
        }
 
        static string LookupSeverity(TraceEventType type)
        { 
            string s; 
            switch (type)
            { 
                case TraceEventType.Critical:
                    s = "Critical";
                    break;
                case TraceEventType.Error: 
                    s = "Error";
                    break; 
                case TraceEventType.Warning: 
                    s = "Warning";
                    break; 
                case TraceEventType.Information:
                    s = "Information";
                    break;
                case TraceEventType.Verbose: 
                    s = "Verbose";
                    break; 
                case TraceEventType.Start: 
                    s = "Start";
                    break; 
                case TraceEventType.Stop:
                    s = "Stop";
                    break;
                case TraceEventType.Suspend: 
                    s = "Suspend";
                    break; 
                case TraceEventType.Transfer: 
                    s = "Transfer";
                    break; 
                default:
                    s = type.ToString();
                    break;
            } 

#pragma warning disable 618 
            AssertUtility.DebugAssert(s == type.ToString(), "Return value should equal the name of the enum"); 
#pragma warning restore 618
            return s; 
        }

        DateTime LastFailure
        { 
            get { return this.lastFailure; }
            set { this.lastFailure = value; } 
        } 

        ///  
        /// Critical - Calls unsafe methods, UnsafeCreateEventLogger and UnsafeLogEvent
        /// TreatAsSafe - Event identities cannot be spoofed as they are constants determined inside the method
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        void LogTraceFailure(string traceString, Exception e)
        { 
            const int FailureBlackoutDuration = 10; 
            TimeSpan FailureBlackout = TimeSpan.FromMinutes(FailureBlackoutDuration);
            try 
            {
                lock (this.localSyncObject)
                {
                    if (DateTime.UtcNow.Subtract(this.LastFailure) >= FailureBlackout) 
                    {
                        this.LastFailure = DateTime.UtcNow; 
#pragma warning disable 618 

                        EventLogger logger = EventLogger.UnsafeCreateEventLogger(this.eventSourceName, this); 
#pragma warning restore 618
                        if (e == null)
                        {
                            logger.UnsafeLogEvent(TraceEventType.Error, EventLogCategory.Tracing, EventLogEventId.FailedToTraceEvent, false, 
                                traceString);
                        } 
                        else 
                        {
                            logger.UnsafeLogEvent(TraceEventType.Error, EventLogCategory.Tracing, EventLogEventId.FailedToTraceEventWithException, false, 
                                traceString,
                                e.ToString());
                        }
 
                    }
                } 
            } 
#pragma warning suppress 56500 //[....]; Taken care of by FxCop
            catch { } 
        }

        void ShutdownTracing()
        { 
            if (null != this.TraceSource && !this.calledShutdown)
            { 
                try 
                {
#pragma warning disable 618 
                    if (this.Level != SourceLevels.Off)
                    {
                        if (this.ShouldTrace(TraceEventType.Information))
#pragma warning restore 618 
                        {
                            Dictionary values = new Dictionary(3); 
                            values["AppDomain.FriendlyName"] = AppDomain.CurrentDomain.FriendlyName; 
                            values["ProcessName"] = DiagnosticTrace.ProcessName;
                            values["ProcessId"] = DiagnosticTrace.ProcessId.ToString(CultureInfo.CurrentCulture); 
                            this.TraceEvent(TraceEventType.Information, TraceCode.AppDomainUnload, TraceSR.GetString(TraceSR.TraceCodeAppDomainUnload),
                                new DictionaryTraceRecord(values), null, null);
                        }
                        this.calledShutdown = true; 
                        this.TraceSource.Flush();
                    } 
                } 
#pragma warning suppress 56500 //[....]; Taken care of by FxCop
                catch (Exception exception) 
                {
                    if (ExceptionUtility.IsFatal(exception))
                    {
                       throw; 
                    }
                    LogTraceFailure(null, exception); 
                } 
            }
        } 

        void ExitOrUnloadEventHandler(object sender, EventArgs e)
        {
            ShutdownTracing(); 
        }
 
        void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args) 
        {
            Exception e = (Exception)args.ExceptionObject; 
            TraceEvent(TraceEventType.Critical, TraceCode.UnhandledException, TraceSR.GetString(TraceSR.UnhandledException), null, e, null);
            ShutdownTracing();
        }
 
        void BuildTrace(TraceEventType type,
                                      TraceCode code, 
                                      string description, 
                                      TraceRecord trace,
                                      Exception exception, 
                                      object source,
                                      out TraceXPathNavigator navigator)
        {
            PlainXmlWriter xmlWriter = new PlainXmlWriter(DiagnosticTrace.MaxTraceSize); 
            navigator = xmlWriter.Navigator;
 
            this.BuildTrace(xmlWriter, type, code, description, trace, exception, source); 

            if (!this.TraceSource.ShouldLogPii) 
            {
                navigator.RemovePii(DiagnosticStrings.HeadersPaths);
            }
        } 

        void BuildTrace(PlainXmlWriter xml, 
                                       TraceEventType type, 
                                       TraceCode code,
                                       string description, 
                                       TraceRecord trace,
                                       Exception exception,
                                       object source)
        { 
            xml.WriteStartElement(DiagnosticStrings.TraceRecordTag);
            xml.WriteAttributeString(DiagnosticStrings.NamespaceTag, DiagnosticTrace.TraceRecordVersion); 
            xml.WriteAttributeString(DiagnosticStrings.SeverityTag, DiagnosticTrace.LookupSeverity(type)); 

            xml.WriteElementString(DiagnosticStrings.TraceCodeTag, GenerateTraceCode(code)); 
            xml.WriteElementString(DiagnosticStrings.DescriptionTag, description);
            xml.WriteElementString(DiagnosticStrings.AppDomain, this.AppDomainFriendlyName);

            if (source != null) 
            {
                xml.WriteElementString(DiagnosticStrings.SourceTag, DiagnosticTrace.CreateSourceString(source)); 
            } 

            if (trace != null) 
            {
                xml.WriteStartElement(DiagnosticStrings.ExtendedDataTag);
                xml.WriteAttributeString(DiagnosticStrings.NamespaceTag, trace.EventId);
 
                trace.WriteTo(xml);
 
                xml.WriteEndElement(); 
            }
 
            if (exception != null)
            {
                xml.WriteStartElement(DiagnosticStrings.ExceptionTag);
                this.AddExceptionToTraceString(xml, exception); 
                xml.WriteEndElement();
            } 
 
            xml.WriteEndElement();
        } 

        static internal Guid ActivityId
        {
            ///  
            /// Critical - gets the CorrelationManager, which does a LinkDemand for UnmanagedCode
            /// Safe - only uses the CorrelationManager to get the ActivityId, which is not protected data 
            ///        doesn't leak the CM 
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            get
            {
                object id = Trace.CorrelationManager.ActivityId;
                return id == null ? Guid.Empty : (Guid)id; 
            }
            ///  
            /// Critical - gets the CorrelationManager, which does a LinkDemand for UnmanagedCode 
            /// Safe - only uses the CorrelationManager to set the ActivityId, which is not protected data
            ///        doesn't leak the CM 
            /// 
            [SecurityCritical, SecurityTreatAsSafe]
            set
            { 
                Trace.CorrelationManager.ActivityId = value;
            } 
        } 

        void AddExceptionToTraceString(XmlWriter xml, Exception exception) 
        {
            xml.WriteElementString(DiagnosticStrings.ExceptionTypeTag, DiagnosticTrace.XmlEncode(exception.GetType().AssemblyQualifiedName));
            xml.WriteElementString(DiagnosticStrings.MessageTag, DiagnosticTrace.XmlEncode(exception.Message));
            xml.WriteElementString(DiagnosticStrings.StackTraceTag, DiagnosticTrace.XmlEncode(this.StackTraceString(exception))); 
            xml.WriteElementString(DiagnosticStrings.ExceptionStringTag, DiagnosticTrace.XmlEncode(exception.ToString()));
            Win32Exception win32Exception = exception as Win32Exception; 
            if (win32Exception != null) 
            {
                xml.WriteElementString(DiagnosticStrings.NativeErrorCodeTag, win32Exception.NativeErrorCode.ToString("X", CultureInfo.InvariantCulture)); 
            }

            if (exception.Data != null && exception.Data.Count > 0)
            { 
                xml.WriteStartElement(DiagnosticStrings.DataItemsTag);
                foreach (object dataItem in exception.Data.Keys) 
                { 
                    xml.WriteStartElement(DiagnosticStrings.DataTag);
                    xml.WriteElementString(DiagnosticStrings.KeyTag, DiagnosticTrace.XmlEncode(dataItem.ToString())); 
                    xml.WriteElementString(DiagnosticStrings.ValueTag, DiagnosticTrace.XmlEncode(exception.Data[dataItem].ToString()));
                    xml.WriteEndElement();
                }
                xml.WriteEndElement(); 
            }
            if (exception.InnerException != null) 
            { 
                xml.WriteStartElement(DiagnosticStrings.InnerExceptionTag);
                this.AddExceptionToTraceString(xml, exception.InnerException); 
                xml.WriteEndElement();
            }
        }
 
        string StackTraceString(Exception exception)
        { 
            string retval = exception.StackTrace; 
            if (string.IsNullOrEmpty(retval))
            { 
                // This means that the exception hasn't been thrown yet. We need to manufacture the stack then.
                StackTrace stackTrace = new StackTrace(false);
                // Figure out how many frames should be throw away
                System.Diagnostics.StackFrame[] stackFrames = stackTrace.GetFrames(); 

                int frameCount = 0; 
                bool breakLoop = false; 
                foreach (StackFrame frame in stackFrames)
                { 
                    string methodName = frame.GetMethod().Name;
                    switch (methodName)
                    {
                        case "StackTraceString": 
                        case "AddExceptionToTraceString":
                        case "BuildTrace": 
                        case "TraceEvent": 
                        case "TraceException":
                            ++frameCount; 
                            break;
                        default:
                            if (methodName.StartsWith("ThrowHelper", StringComparison.Ordinal))
                            { 
                                ++ frameCount;
                            } 
                            else 
                            {
                                breakLoop = true; 
                            }
                            break;
                    }
                    if (breakLoop) 
                    {
                        break; 
                    } 
                }
 
                stackTrace = new StackTrace(frameCount, false);
                retval = stackTrace.ToString();
            }
            return retval; 
        }
 
        //only used for exceptions, perf is not important 
        static internal string XmlEncode(string text)
        { 
            if (string.IsNullOrEmpty(text))
            {
                return text;
            } 

            int len = text.Length; 
            StringBuilder encodedText = new StringBuilder(len + 8); //perf optimization, expecting no more than 2 > characters 

            for (int i = 0; i < len; ++i) 
            {
                char ch = text[i];
                switch (ch)
                { 
                    case '<':
                        encodedText.Append("<"); 
                        break; 
                    case '>':
                        encodedText.Append(">"); 
                        break;
                    case '&':
                        encodedText.Append("&");
                        break; 
                    default:
                        encodedText.Append(ch); 
                        break; 
                }
            } 
            return encodedText.ToString();
        }

    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK