I need to measure the bandwidth of an application I've made. Let's say that this application is called myapp.exe
.
I have made a library called BandwidthMonitor
(BM) which is called from within myapp.exe
. myapp.exe
periodically calls BM.Measure()
which returns a BandwidthMeasurement
.
My BM
looks like this:
public class BandwidthMonitor
{
PerformanceCounter bandwidthCounter;
PerformanceCounter dataReceivedCounter;
PerformanceCounter dataSentCounter;
List<float> byetsSent = new List<float>();
List<float> byetsReceived = new List<float>();
List<float> byetsUtilization = new List<float>();
float bandwidth;
int ticks = 0;
static string categoryName = ".NET CLR Networking 4.0.0.0";
public BandwidthMonitor()
{
try
{
bandwidthCounter = new PerformanceCounter();
bandwidthCounter.CategoryName = categoryName;
bandwidthCounter.CounterName = "Current Bandwidth";
bandwidthCounter.InstanceName = instance;
bandwidthCounter.ReadOnly = true;
dataReceivedCounter = new PerformanceCounter();
dataReceivedCounter.CategoryName = categoryName;
dataReceivedCounter.CounterName = "Bytes Received/sec";
dataReceivedCounter.InstanceName = instance;
dataReceivedCounter.ReadOnly = true;
dataSentCounter = new PerformanceCounter();
dataSentCounter.CategoryName = categoryName;
dataSentCounter.CounterName = "Bytes Sent/sec";
dataSentCounter.InstanceName = instance;
dataSentCounter.ReadOnly = true;
Console.WriteLine("Bandwidth monitor ready.");
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
public BandwidthMeasurement Measure()
{
var measurement = new BandwidthMeasurement();
ticks++;
try
{
var bytesSent = dataSentCounter.RawValue;
var bytesReceived = dataReceivedCounter.RawValue;
measurement.BytesSent = bytesSent;
measurement.ByesReceived = bytesReceived;
double utilization = (8 * (bytesSent + bytesReceived)) / (bandwidth * ticks) * 100;
measurement.Utilization = utilization;
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
return measurement;
}
//https://stackoverflow.com/a/27418721/596841
private static string GetInstanceName()
{
string returnvalue = "not found";
//Checks bandwidth usage for CUPC.exe..Change it with your application Name
string applicationName = "myapp";
PerformanceCounterCategory[] Array = PerformanceCounterCategory.GetCategories();
for (int i = 0; i < Array.Length; i++)
{
if (Array[i].CategoryName.Contains(categoryName))
foreach (var item in Array[i].GetInstanceNames())
{
Console.WriteLine(item);
if (item.ToLower().Contains(applicationName.ToString().ToLower()))
returnvalue = item;
}
}
return returnvalue;
}
}
For some reason, GetInstanceName()
always returns not found
. I cannot figure out why.
I've tried:
- settings
categoryName
to.NET CLR Networking
- passing
myapp
processId
to theBM
and looking up the category. - delaying the point at which
BM
is instantiated so as to ensuremyapp
is fully loaded and operational first (pretty pointless, I think, but I don't know what else to try... grasping at straws here!).
PerformanceCounterCategory category = new PerformanceCounterCategory(".NET CLR Networking 4.0.0.0"); // and without the 4.0.0.0
var instanceNames = category.GetInstanceNames().Where(i => i.Contains(string.Format("p{0}", processId)));
if (instanceNames.Count() == 0) throw new Exception("Instance name not found");
Passing the processId does not find the instance name, either.
I keep getting the exception:
Could not locate performance counter with specified category name ".NET CLR Networking 4.0.0.0".
What am I doing wrong?