ThreadTrace.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 / ServiceModel / System / ServiceModel / ThreadTrace.cs / 1 / ThreadTrace.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel
{ 
    using System;
    using System.IO; 
    using System.Threading; 
    using System.Security;
    using System.Runtime.InteropServices; 
    using System.Collections.Generic;
    using System.Runtime.CompilerServices;

    // Enable this code to track which thread operations occur on 
#if false
    static class ThreadTrace 
    { 
        static LocalDataStoreSlot slot;
        static List logs; 
        static string logFileName;
        static bool isEnabled;
        static long frequency;
 
        static ThreadTrace()
        { 
            logFileName = Environment.GetEnvironmentVariable("ThreadTrace"); 
            if (logFileName == null)
                logFileName = ""; 
            isEnabled = logFileName.Length > 0;
            if (isEnabled)
            {
                slot = Thread.AllocateDataSlot(); 
                logs = new List();
                NativeMethods.QueryPerformanceFrequency(out frequency); 
                Console.WriteLine("ThreadTrace: enabled"); 
                new Thread(ThreadProc).Start();
            } 
        }

        static bool stopTracing;
 
        public static void StopTracing()
        { 
            stopTracing = true; 
        }
 
        static void ThreadProc()
        {
            while (!stopTracing)
            { 
                Thread.Sleep(20000);
                WriteLogFile(); 
                Console.WriteLine("ThreadTrace: " + logFileName + " saved."); 
            }
        } 

        static object ThisLock
        {
            get { return logs; } 
        }
 
        public static void Trace(string operation) 
        {
            if (isEnabled) 
            {
                TraceInternal(operation);
            }
        } 

        [MethodImpl(MethodImplOptions.NoInlining)] 
        static void TraceInternal(string operation) 
        {
            long time; 
            NativeMethods.QueryPerformanceCounter(out time);
            ThreadLog log = (ThreadLog)Thread.GetData(slot);
            if (log == null)
            { 
                Thread currentThread = Thread.CurrentThread;
                log = new ThreadLog(currentThread); 
                lock (ThisLock) 
                {
                    logs.Add(log); 
                }
                Thread.SetData(slot, log);
            }
            log.Append(time, operation); 
        }
 
        static void WriteLogFile() 
        {
            Trace("ThreadTrace.Save"); 
            TextWriter writer = File.CreateText(logFileName);
            using (writer)
            {
                ThreadLogSnapshot[] logSnapshots = new ThreadLogSnapshot[logs.Count]; 
                writer.Write("Time");
                for (int i = 0; i < logs.Count; i++) 
                { 
                    logSnapshots[i] = logs[i].GetSnapshot();
                    writer.Write(", Thread "); 
                    writer.Write(i.ToString());
                }
                writer.WriteLine();
                writer.Write("(Ms)"); 
                foreach (ThreadLog log in logs)
                { 
                    if (log.IsThreadPoolThread) 
                        writer.Write(", (ThreadPool)");
                    else if (log.IsBackgroundThread) 
                        writer.Write(", (Background)");
                    else
                        writer.Write(", (Main)");
                } 
                writer.WriteLine();
                int[] indices = new int[logs.Count]; 
                int count = 0; 
                for (int i = 0; i < logs.Count; i++)
                    count += logSnapshots[i].Count; 
                for (int j = 0; j < count; j++)
                {
                    int earliestIndex = -1;
                    long earliestTime = long.MaxValue; 
                    for (int i = 0; i < logs.Count; i++)
                    { 
                        ThreadLogSnapshot logSnapshot = logSnapshots[i]; 
                        int index = indices[i];
                        if (index >= logSnapshot.Count) 
                            continue;
                        long time = logSnapshot[index].time;
                        if (time < earliestTime)
                        { 
                            earliestIndex = i;
                            earliestTime = time; 
                        } 
                    }
                    ThreadLogEntry entry = logSnapshots[earliestIndex][indices[earliestIndex]]; 
                    double timeInMilliseconds = (entry.time * 1000) / (double)frequency;
                    writer.Write(timeInMilliseconds);
                    for (int i = 0; i < logs.Count; i++)
                    { 
                        writer.Write(", ");
                        if (i == earliestIndex) 
                        { 
                            writer.Write('\"');
                            writer.Write(entry.operation); 
                            writer.Write('\"');
                        }
                    }
                    writer.WriteLine(); 
                    indices[earliestIndex]++;
                } 
            } 
        }
 
        struct ThreadLogEntry
        {
            public long time;
            public string operation; 

            public ThreadLogEntry(long time, string operation) 
            { 
                this.time = time;
                this.operation = operation; 
            }
        }

        class ThreadLogSnapshot 
        {
            ThreadLogEntry[] entries; 
 
            public ThreadLogSnapshot(ThreadLogEntry[] entries)
            { 
                this.entries = entries;
            }

            public int Count 
            {
                get 
                { 
                    return this.entries.Length;
                } 
            }

            public ThreadLogEntry this[int index]
            { 
                get
                { 
                    return this.entries[index]; 
                }
            } 
        }

        class ThreadLog
        { 
            int count;
            ThreadLogEntry[] buffer; 
            const int bufferSize = 5000; 
            const int maxBuffers = 4096;
            bool isThreadPoolThread; 
            bool isBackgroundThread;
            ThreadLogEntry[][] buffers;
            int bufferCount;
 
            public ThreadLog(Thread thread)
            { 
                this.isThreadPoolThread = thread.IsThreadPoolThread; 
                this.isBackgroundThread = thread.IsBackground;
                this.buffer = new ThreadLogEntry[bufferSize]; 
                this.buffers = new ThreadLogEntry[maxBuffers][];
            }

            object ThisLock 
            {
                get { return this; } 
            } 

            public bool IsThreadPoolThread 
            {
                get { return this.isThreadPoolThread; }
            }
 
            public bool IsBackgroundThread
            { 
                get { return this.isBackgroundThread; } 
            }
 
            public void Append(long time, string operation)
            {
                if (this.count == bufferSize)
                { 
                    lock (ThisLock)
                    { 
                        this.buffers[bufferCount++] = this.buffer; 
                        this.buffer = new ThreadLogEntry[bufferSize];
                        this.count = 0; 
                    }
                }

                this.buffer[this.count++] = new ThreadLogEntry(time, operation); 
            }
 
            public ThreadLogSnapshot GetSnapshot() 
            {
                int currentBufferCount; 
                int currentCount;
                ThreadLogEntry[] currentBuffer;

                lock (ThisLock) 
                {
                    currentBufferCount = this.bufferCount; 
                    currentCount = this.count; 
                    currentBuffer = this.buffer;
                } 

                ThreadLogEntry[] entries = new ThreadLogEntry[currentBufferCount * bufferSize + currentCount];
                int index = 0;
                for (int i = 0; i < currentBufferCount; i++) 
                {
                    Array.Copy(buffers[i], 0, entries, index, bufferSize); 
                    index += bufferSize; 
                }
                Array.Copy(currentBuffer, 0, entries, index, currentCount); 
                return new ThreadLogSnapshot(entries);
            }
        }
 
        [SuppressUnmanagedCodeSecurity]
        static class NativeMethods 
        { 
            [DllImport("kernel32.dll")]
            public static extern int QueryPerformanceCounter(out long time); 

            [DllImport("kernel32.dll")]
            public static extern int QueryPerformanceFrequency(out long frequency);
        } 
    }
#else 
    static class ThreadTrace 
    {
        public static void Trace(string operation) 
        {
        }

        public static void StopTracing() 
        {
        } 
 
        public static void Save()
        { 
        }
    }
#endif
} 

// 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