public static CpuUsage Substruct(CpuUsage onEnd, CpuUsage onStart) { var user = onEnd.UserUsage.TotalMicroSeconds - onStart.UserUsage.TotalMicroSeconds; var system = onEnd.KernelUsage.TotalMicroSeconds - onStart.KernelUsage.TotalMicroSeconds; return(new CpuUsage(user, system)); }
public static CpuUsage Add(CpuUsage one, CpuUsage two) { long user = one.UserUsage.TotalMicroSeconds + two.UserUsage.TotalMicroSeconds; long system = one.KernelUsage.TotalMicroSeconds + two.KernelUsage.TotalMicroSeconds; return(new CpuUsage(user, system)); }
private void ContextChangedHandler(AsyncLocalValueChangedArgs <object> args) { // if (!args.ThreadContextChanged) return; if (!IsRunning) { return; } long tid = GetThreadId(); if (args.PreviousValue == null) { ContextItem.Value = new ContextSwitchInfo() { ThreadId = tid, StartAt = Stopwatch.StartNew(), UsageOnStart = CpuUsageReader.GetByThread().Value, }; } else if (args.CurrentValue == null) { var contextOnStart = ContextItem.Value; ContextItem.Value = null; if (contextOnStart == null) { throw new InvalidOperationException( "CpuUsageAsyncWatcher.OnEnd: Missing contextOnStart. Please report"); } if (tid != contextOnStart.ThreadId) { throw new InvalidOperationException( $"CpuUsageAsyncWatcher.OnEnd: ContextItem.Value.ThreadId is not as expected." + $"Thread.CurrentThread.ManagedThreadId is {tid}. " + $"contextOnStart.ThreadId is {contextOnStart.ThreadId}. Please report"); } var ticks = contextOnStart.StartAt.ElapsedTicks; var duration = ticks / (double)Stopwatch.Frequency; var usageOnEnd = CpuUsageReader.GetByThread().Value; var cpuUsage = CpuUsage.Substruct(usageOnEnd, contextOnStart.UsageOnStart); ContextSwitchMetrics logRow = new ContextSwitchMetrics() { Duration = duration, CpuUsage = cpuUsage }; lock (_Log) _Log.Add(logRow); } #if DEBUG Console.ForegroundColor = ConsoleColor.Cyan; string AsString(object value) => value == null ? "off" : Convert.ToString(value); Console.WriteLine($"Value Changed {(args.ThreadContextChanged ? $"WITH context #{tid}" : $"WITHOUT context #{tid}")}: {AsString(args.PreviousValue)} => {AsString(args.CurrentValue)}");