in Source/Tx.Windows/PerfCounters/PerfCounterReader.cs [26:74]
internal void ProduceCounterSamples(PerfCounterInfo counterInfo, DateTime timestamp)
{
uint bufferSize = 0;
uint bufferCount;
PdhStatus status = PdhNativeMethods.PdhGetFormattedCounterArray(
counterInfo.Handle,
PdhFormat.PDH_FMT_DOUBLE,
ref bufferSize,
out bufferCount,
IntPtr.Zero);
PdhUtils.CheckStatus(status, PdhStatus.PDH_MORE_DATA);
var buffer = new byte[bufferSize];
unsafe
{
fixed (byte* pb = buffer)
{
status = PdhNativeMethods.PdhGetFormattedCounterArray(
counterInfo.Handle,
PdhFormat.PDH_FMT_DOUBLE,
ref bufferSize,
out bufferCount,
(IntPtr) pb);
if (status == PdhStatus.PDH_INVALID_DATA
|| status == PdhStatus.PDH_NO_DATA
|| status == PdhStatus.PDH_CALC_NEGATIVE_VALUE
|| status == PdhStatus.PDH_CALC_NEGATIVE_DENOMINATOR
|| status == PdhStatus.PDH_CALC_NEGATIVE_TIMEBASE)
{
var sample = new PerformanceSample(counterInfo, counterInfo.Instance, timestamp, double.NaN);
_observer.OnNext(sample);
return;
}
PdhUtils.CheckStatus(status, PdhStatus.PDH_CSTATUS_VALID_DATA);
var items = (PDH_FMT_COUNTERVALUE_ITEM*) pb;
for (int i = 0; i < bufferCount; i++)
{
PDH_FMT_COUNTERVALUE_ITEM* item = items + i;
var instanceName = new string((char*)item->szName);
var sample = new PerformanceSample(counterInfo, instanceName, timestamp, item->FmtValue.doubleValue);
_observer.OnNext(sample);
}
}
}
}