private static void UpdateProfilerForEntering(EneterTrace trace) { int aThreadId = Thread.CurrentThread.ManagedThreadId; Action aProfilerJob = () => { MethodBase aMethod = trace.myCallStack.GetMethod(); lock (myProfilerData) { ProfilerData aProfileData; myProfilerData.TryGetValue(aMethod, out aProfileData); if (aProfileData == null) { aProfileData = new ProfilerData(); aProfileData.Calls = 1; aProfileData.MaxConcurency = 1; aProfileData.MaxRecursion = 1; aProfileData.Threads[aThreadId] = 1; myProfilerData[aMethod] = aProfileData; } else { ++aProfileData.Calls; // If this thread is already inside then it is a recursion. if (aProfileData.Threads.ContainsKey(aThreadId)) { int aRecursion = ++aProfileData.Threads[aThreadId]; if (aRecursion > aProfileData.MaxRecursion) { aProfileData.MaxRecursion = aRecursion; } } // ... else it is another thread wich is parallel inside. else { aProfileData.Threads[aThreadId] = 1; if (aProfileData.Threads.Count > aProfileData.MaxConcurency) { aProfileData.MaxConcurency = aProfileData.Threads.Count; } } } trace.myBufferedProfileData = aProfileData; } }; EnqueueJob(aProfilerJob); }
private static void UpdateProfilerForLeaving(EneterTrace trace, long ticks) { int aThreadId = Thread.CurrentThread.ManagedThreadId; Action aProfilerJob = () => { lock (myProfilerData) { trace.myBufferedProfileData.Ticks += ticks; int aRecursion = --trace.myBufferedProfileData.Threads[aThreadId]; if (aRecursion < 1) { MethodBase aMethod = trace.myCallStack.GetMethod(); ProfilerData aProfileData = myProfilerData[aMethod]; aProfileData.Threads.Remove(aThreadId); } } }; EnqueueJob(aProfilerJob); }
/// <summary> /// Traces entering-leaving the method. /// </summary> /// <remarks> /// The enetering information for the method calling this constructor is put to the trace /// and the measuring of the time starts. /// In order to trace entering-leaving, the detail level must be set to 'Debug'. /// </remarks> public static IDisposable Entering(string additionalInfo = null) { EneterTrace aTraceObject = null; if (DetailLevel > EDetailLevel.Short || myProfilerIsRunning) { aTraceObject = new EneterTrace(); aTraceObject.myCallStack = new StackFrame(1); long aEnteringTimeTicks = !myProfilerIsRunning ? DateTime.Now.Ticks : 0; aTraceObject.myEnteringTicks = Stopwatch.GetTimestamp(); if (myProfilerIsRunning) { UpdateProfilerForEntering(aTraceObject); } else { WriteMessage(aTraceObject.myCallStack, aEnteringTimeTicks, ENTERING, additionalInfo); } } return(aTraceObject); }