public static extern unsafe int FormatFromRawValue( uint dwCounterType, uint dwFormat, ref long pTimeBase, ref Interop.Kernel32.PerformanceCounterOptions.PDH_RAW_COUNTER pRawValue1, ref Interop.Kernel32.PerformanceCounterOptions.PDH_RAW_COUNTER pRawValue2, ref Interop.Kernel32.PerformanceCounterOptions.PDH_FMT_COUNTERVALUE pFmtValue );
/// <summary> /// Computes the calculated value given a raw counter sample. /// </summary> public static float ComputeCounterValue(CounterSample oldSample, CounterSample newSample) { int newCounterType = (int)newSample.CounterType; if (oldSample.SystemFrequency == 0) { if ((newCounterType != Interop.Kernel32.PerformanceCounterOptions.PERF_RAW_FRACTION) && (newCounterType != Interop.Kernel32.PerformanceCounterOptions.PERF_COUNTER_RAWCOUNT) && (newCounterType != Interop.Kernel32.PerformanceCounterOptions.PERF_COUNTER_RAWCOUNT_HEX) && (newCounterType != Interop.Kernel32.PerformanceCounterOptions.PERF_COUNTER_LARGE_RAWCOUNT) && (newCounterType != Interop.Kernel32.PerformanceCounterOptions.PERF_COUNTER_LARGE_RAWCOUNT_HEX) && (newCounterType != Interop.Kernel32.PerformanceCounterOptions.PERF_COUNTER_MULTI_BASE)) { // Since oldSample has a system frequency of 0, this means the newSample is the first sample // on a two sample calculation. Since we can't do anything with it, return 0. return(0.0f); } } else if (oldSample.CounterType != newSample.CounterType) { throw new InvalidOperationException(SR.MismatchedCounterTypes); } if (newCounterType == Interop.Kernel32.PerformanceCounterOptions.PERF_ELAPSED_TIME) { return((float)GetElapsedTime(oldSample, newSample)); } Interop.Kernel32.PerformanceCounterOptions.PDH_RAW_COUNTER newPdhValue = new Interop.Kernel32.PerformanceCounterOptions.PDH_RAW_COUNTER(); Interop.Kernel32.PerformanceCounterOptions.PDH_RAW_COUNTER oldPdhValue = new Interop.Kernel32.PerformanceCounterOptions.PDH_RAW_COUNTER(); FillInValues(oldSample, newSample, ref oldPdhValue, ref newPdhValue); LoadPerfCounterDll(); Interop.Kernel32.PerformanceCounterOptions.PDH_FMT_COUNTERVALUE pdhFormattedValue = new Interop.Kernel32.PerformanceCounterOptions.PDH_FMT_COUNTERVALUE(); long timeBase = newSample.SystemFrequency; int result = Interop.PerfCounter.FormatFromRawValue((uint)newCounterType, Interop.Kernel32.PerformanceCounterOptions.PDH_FMT_DOUBLE | Interop.Kernel32.PerformanceCounterOptions.PDH_FMT_NOSCALE | Interop.Kernel32.PerformanceCounterOptions.PDH_FMT_NOCAP100, ref timeBase, ref newPdhValue, ref oldPdhValue, ref pdhFormattedValue); if (result != Interop.Errors.ERROR_SUCCESS) { // If the numbers go negative, just return 0. This better matches the old behavior. if (result == Interop.Kernel32.PerformanceCounterOptions.PDH_CALC_NEGATIVE_VALUE || result == Interop.Kernel32.PerformanceCounterOptions.PDH_CALC_NEGATIVE_DENOMINATOR || result == Interop.Kernel32.PerformanceCounterOptions.PDH_NO_DATA) { return(0); } else { throw new Win32Exception(result, SR.Format(SR.PerfCounterPdhError, result.ToString("x", CultureInfo.InvariantCulture))); } } return((float)pdhFormattedValue.data); }