Measure the consumed mb on the internet - c#

I want to get the number of consumed MBs on the internet by code..
I know that it can be done manually:
Settings -> Network & Internet -> Data Usage (Windows 10)
photo:
But how can I find this by code?
I want the number for the whole system, NOT ONLY MY APPLICATION.
For example, I want my code to show: The GB used this month was 3.21!

You can try the following snippet which will give you total sent and received data. You just need to sum it out:
private static void GetTrafficStatistics()
{
PerformanceCounterCategory performanceCounterCategory = new PerformanceCounterCategory("Network Interface");
string instance = performanceCounterCategory.GetInstanceNames()[0]; // 1st NIC !
PerformanceCounter performanceCounterSent = new PerformanceCounter("Network Interface", "Bytes Sent/sec", instance);
PerformanceCounter performanceCounterReceived = new PerformanceCounter("Network Interface", "Bytes Received/sec", instance);
for (int i = 0; i < 10; i++)
{
Console.WriteLine("bytes sent: {0}k\tbytes received: {1}k", performanceCounterSent.NextValue() / 1024, performanceCounterReceived.NextValue() / 1024);
Thread.Sleep(500);
}
}
PS:It is using System.Diagnostics.dll
Hope it will help you out.

Related

How to get the current CPU/RAM/Disk usage in a C# web application using .NET CORE?

I am currently looking for a way to get the current CPU/RAM/Disk usage in a C# web application using .NET CORE.
For CPU and ram usage, I use PerformanceCounter Class from System.Diagnostics.
This is the codes:
PerformanceCounter cpuCounter;
PerformanceCounter ramCounter;
cpuCounter = new PerformanceCounter();
cpuCounter.CategoryName = "Processor";
cpuCounter.CounterName = "% Processor Time";
cpuCounter.InstanceName = "_Total";
ramCounter = new PerformanceCounter("Memory", "Available MBytes");
public string getCurrentCpuUsage(){
cpuCounter.NextValue()+"%";
}
public string getAvailableRAM(){
ramCounter.NextValue()+"MB";
}
For disk usage, I am using the DriveInfo class. This is the codes:
using System;
using System.IO;
class Info {
public static void Main() {
DriveInfo[] drives = DriveInfo.GetDrives();
foreach (DriveInfo drive in drives) {
//There are more attributes you can use.
//Check the MSDN link for a complete example.
Console.WriteLine(drive.Name);
if (drive.IsReady) Console.WriteLine(drive.TotalSize);
}
}
}
Unfortunately .NET Core does not support the DriveInfo and PerformanceCounter classes, hence the code above do not work.
Does anyone know how I can get the current CPU/RAM/Disk usage in a C# web application using .NET CORE?
You can use PerformnceCounter in the System.Diagnostics.PerformanceCounter package
for example, the next code will give you the total processor usage percent
var cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total",true);
var value = cpuCounter.NextValue();
//Note: In most cases you need to call .NextValue() twice to be able to get the real value
if (Math.Abs(value) <= 0.00)
value = cpuCounter.NextValue();
Console.WriteLine(value);
you can do the same for all OS registered Performance Counters.
Update:
I'm not sure if there is something I should do after creating a new instance of the PerformanceCounter class, but sometimes when I get the next value it comes as 0.
So I've decided to make one instance of PerformanceCounter in at the application level.
e.g.
public static class DiagnosticHelpers
{
static float _systemCPU;
public static float SystemCPU
{
get
{
lock (locker)
{
return _systemCPU;
}
}
}
private static readonly object locker = new object();
static DiagnosticHelpers()
{
SystemCPU = 0;
Task.Run(() =>
{
var cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total", true);
cpuCounter.NextValue(); //prime the counter
while (true)
{
Thread.Sleep(1000); /wait at least 1 second before the first real read
lock (locker)
{
_systemCPU = cpuCounter.NextValue();
}
}
});
}
}
Processor information is available via System.Diagnostics:
var proc = Process.GetCurrentProcess();
var mem = proc.WorkingSet64;
var cpu = proc.TotalProcessorTime;
Console.WriteLine("My process used working set {0:n3} K of working set and CPU {1:n} msec",
mem / 1024.0, cpu.TotalMilliseconds);
DriveInfo is available for Core by adding the System.IO.FileSystem.DriveInfo package
For Windows i'm using this
var memorieLines= GetWmicOutput("OS get FreePhysicalMemory,TotalVisibleMemorySize /Value").Split("\n");
var freeMemory= memorielines[0].Split("=", StringSplitOptions.RemoveEmptyEntries)[1];
var totalMemory = memorielines[1].Split("=", StringSplitOptions.RemoveEmptyEntries)[1];
var cpuLines = GetWmicOutput("CPU get Name,LoadPercentage /Value").Split("\n");
var CpuUse = cpuLines[0].Split("=", StringSplitOptions.RemoveEmptyEntries)[1];
var CpuName = cpuLines[1].Split("=", StringSplitOptions.RemoveEmptyEntries)[1];
private string GetWmicOutput(string query, bool redirectStandardOutput = true)
{
var info = new ProcessStartInfo("wmic");
info.Arguments = query;
info.RedirectStandardOutput = redirectStandardOutput;
var output = string.Empty;
using (var process = Process.Start(info))
{
output = process.StandardOutput.ReadToEnd();
}
return output.Trim();
}
For the disk infos you can use this query :
LOGICALDISK get Caption,DeviceID,FileSystem,FreeSpace,Size /Value
if you want a better output formatting give a look to this article : https://www.petri.com/command-line-wmi-part-3
Add this nuget package to your project by double clicking project.
<ItemGroup>
<PackageReference Include="System.Diagnostics.PerformanceCounter" Version="6.0.0" />
</ItemGroup>
When you run the code, you will get an error like below.
Performance counters cannot be initialized! System.UnauthorizedAccessException: Access to the registry key 'Global' is denied.
To solve this error, you have to add your application pool user to "Performance Monitor Users" group.
Open command line in administrator mode, then run this command.
net localgroup "Performance Monitor Users" "IIS APPPOOL\MYAPPPOOL" /add
MYAPPPOOL will be replaced with your real app pool name.
Then restart the machine if iis restart does not solve.

How to get Committed Memory in Windows Server 2012 using .NET

This is how I get the total and used RAM:
PerformanceCounter ramAvailableCounter = new PerformanceCounter("Memory", "Available MBytes");
var ramUsedMB = ramAvailableCounter.NextValue();
var ramTotalMB = new Microsoft.VisualBasic.Devices.ComputerInfo().TotalPhysicalMemory / 1024 / 1024;
var ramPercentageLeft = (ramUsedMB * 100) / ramTotalMB;
But how can I get the "Committed" memory shown below?
Unfortunately the application we use throws an exception when there is only about 15GB free and I would like to send a notification when is close enough.
It can be done as following:
PerformanceCounter percCommittedBytesInUseCounter = new PerformanceCounter("Memory", "% Committed Bytes In Use");

C# Instance Name to Use For Network Interface Performance Counter

I'm trying to add some system monitoring functions to a WPF app I am working on and I would like to add a bandwidth use monitor. Right now I have a CPU and a RAM counter working but I can't figure out what to use for the Performance Counter instance name (sorry if that isn't the correct term). This is what I'm using so far:
PerformanceCounter cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
PerformanceCounter ramCounter = new PerformanceCounter("Memory", "Available MBytes", string.Empty);
PerformanceCounter netSentCounter = new PerformanceCounter("Network Interface", "Bytes Received/sec", );
PerformanceCounter netRecCounter = new PerformanceCounter("Network Interface", "Bytes Sent/sec", );
I have strings that update every 1 second using a timer tick method that updates my WPF labels and the RAM and the CPU counters work but I don't know what to put for the instance names for the last two network interfaces.
Thanks in advance.
Here is some sample code how to iterate through the Network Interfaces;
PerformanceCounterCategory category = new PerformanceCounterCategory("Network Interface");
String[] instancename = category.GetInstanceNames();
foreach (string name in instancename)
{
Console.WriteLine(name);
}
By utilizing the PerformanceCounterCategory, you can now obtain the Instance Names, and then use in your PerformanceCounter(s) using GetInstanceNames.

High CPU load using WCF streaming

I've been doing a lot of research on this issue but unfortunately I wasn't able to find a solution.
My problem is that I am experiencing a quite high CPU load even on powerful machines when using WCF (NetTcpBinding, Streamed) - to be more specific, my i5 860 has a load of 20-40 percent when handling 20 client threads. When it comes to deploying a real service (and not a testing project) and there's around 50 real clients sending small data packages every second (around 20kb per transfer) the CPU load is already at 80-90 percent. In the end there should be 200+ clients but I can't imagine how this should work with such CPU loads...
For testing purposes I have set up a small project with just a simple client and server based on WCF streamed transfer using NetTcpBinding. There's already a lot of 'desperation code' in it, because I have tried to make it work... for my testing I used a 200MB file that's being sent to the WCF service 20 times.
Here's the contract:
[ServiceContract(Namespace = "WCFStreamTest.WCFService")]
public interface IStreamContract
{
[OperationContract(Name = "ReceiveStream")]
StreamMessage ReceiveStream(StreamMessage msg);
[OperationContract(Name = "SendStream")]
StreamMessage SendStream(StreamMessage msg);
}
The StreamMessage class used in here is just a MessageContract containing a string header and a Stream object.
The server code looks as follows:
[ServiceBehavior(IncludeExceptionDetailInFaults = false, InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = true, MaxItemsInObjectGraph = int.MaxValue)]
public class StreamService : IStreamContract
{
public StreamMessage ReceiveStream(StreamMessage msg)
{
if (File.Exists(msg.Parameters))
return new StreamMessage() { Parameters = msg.Parameters, DataStream = new System.IO.FileStream(msg.Parameters, System.IO.FileMode.Open, System.IO.FileAccess.Read) };
return new StreamMessage();
}
public StreamMessage SendStream(StreamMessage msg)
{
if (msg.Parameters.Trim().Length > 0)
{
int bufferSize = 8096 * 4;
byte[] buffer = new byte[bufferSize];
int bytes = 0;
while ((bytes = msg.DataStream.Read(buffer, 0, bufferSize)) > 0)
{
byte b = buffer[0];
b = (byte)(b + 1);
}
}
return new StreamMessage();
}
}
The test project just uses the SendStream method for testing - and that method just reads the data stream and does nothing else.
At this point I think I'll just save your time reading and don't post the full code in here. Maybe a download link to the demo project will be sufficient? (To make it work there is one line in the client's Program.cs that's object to be changed: FileInfo fi = new FileInfo(#"<<<>>>");)
WCFStreamTest Project
I'd be really happy about any idea on how to lower CPU usage... thanks in advance for any help and tips...
Can you try to make the thread sleep in while loop, and see how it goes.
while ((bytes = msg.DataStream.Read(buffer, 0, bufferSize)) > 0)
{
byte b = buffer[0];
b = (byte)(b + 1);
Thread.Sleep(100);
}
If it is a video streaming service you might have to tweak the sleep interval.

Retrieving Total amount of RAM on a computer [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
C# - How do you get total amount of RAM the computer has?
The following would retrieve how much ram is available:
PerformanceCounter ramCounter;
ramCounter = new PerformanceCounter("Memory", "Available MBytes");
Console.WriteLine("Total RAM: " + ramCounter.NextValue().ToString() + " MB\n\n");
Of course we will have to use the System.Diagnostics; class.
Does performancecounter have any functionality for retrieving the amount of RAM of a particular machine? I'm not talking about the amount of ram used or unused. I'm talking about the amount of ram the machine has.
This information is already available directly in the .NET framework, you might as well use it. Project + Add Reference, select Microsoft.VisualBasic.
using System;
class Program {
static void Main(string[] args) {
Console.WriteLine("You have {0} bytes of RAM",
new Microsoft.VisualBasic.Devices.ComputerInfo().TotalPhysicalMemory);
Console.ReadLine();
}
}
And no, it doesn't turn your C# code into vb.net.
you can try like this
Add a Reference to System.Management.
private static void DisplayTotalRam()
{
string Query = "SELECT MaxCapacity FROM Win32_PhysicalMemoryArray";
ManagementObjectSearcher searcher = new ManagementObjectSearcher(Query);
foreach (ManagementObject WniPART in searcher.Get())
{
UInt32 SizeinKB = Convert.ToUInt32(WniPART.Properties["MaxCapacity"].Value);
UInt32 SizeinMB = SizeinKB / 1024;
UInt32 SizeinGB = SizeinMB / 1024;
Console.WriteLine("Size in KB: {0}, Size in MB: {1}, Size in GB: {2}", SizeinKB, SizeinMB, SizeinGB);
}
}

Categories

Resources