Stian Tofte
Stian Tofte

Reputation: 213

Get process by PID and monitor memory ussage

I'm having a little trouble monitoring memory usage of an application. I already have some code that gets the process by name.. But there can be multiple processes with the same name. So it will only monitor the first process in the list.. So I'm trying to get it by PID. But I have no code that works.. But here is what I used when I got it by name:

private void SetMemory()
    {
        PerformanceCounter performanceCounter = new PerformanceCounter
        {
            CategoryName = "Process",
            CounterName = "Working Set",
            InstanceName = MinecraftProcess.Process.ProcessName
        };
        try
        {
            string text = ((uint)performanceCounter.NextValue() / 1024 / 1000).ToString("N0") + " MB";
            MemoryValue.Text = text;
            radProgressBar1.Value1 = ((int)performanceCounter.NextValue() / 1024 / 1000);
        }
        catch (Exception ex)
        {

        }
    }

EDIT: I have the PID. But I don't know how to start the monitoring from that.

Upvotes: 3

Views: 3069

Answers (2)

keenthinker
keenthinker

Reputation: 7830

You have many possibilities to constantly observe the memory consuption of the process. One of them is (for example if you do not have UI application) to start a task (using the .NET Task Parallel Library), that continuosly polls the memory consuption. The first step is to get the process (by name or by PID and take the current memory usage. The easiest way to do this is as @Jurgen Camilleri suggested:

private void checkMemory(Process process)
{
    try
    {           
        if (process != null)
        {
            Console.WriteLine("Memory Usage: {0} MB", process.WorkingSet64 / 1024 / 1024);
        }
    }
    catch (Exception exception)
    {
        Console.WriteLine(exception.Message);
    }
}

Using WorkingSet(64) is the closest info to the task manager memory usage (that you can get that simple). The polling code:

var cancellationTokenSource = new CancellationTokenSource();
var cancellationToken = cancellationTokenSource.Token;
// take the first firefox instance once; if you know the PID you can use Process.GetProcessById(PID);
var firefox = Process.GetProcessesByName("firefox").FirstOrDefault();
var timer = new System.Threading.Tasks.Task(() =>
{
    cancellationToken.ThrowIfCancellationRequested();
    // poll
    while (true)
    {
        checkMemory(firefox);
        // we want to exit
        if (cancellationToken.IsCancellationRequested)
        {
            cancellationToken.ThrowIfCancellationRequested();
        }
        // give the system some time
        System.Threading.Thread.Sleep(1000);
    }
}, cancellationToken);
// start the polling task
timer.Start();
// poll for 2,5 seconds
System.Threading.Thread.Sleep(2500);
// stop polling
cancellationTokenSource.Cancel();

If you have a windows forms / WPF application that is running, you could use for example timers (and their callback method, for example the System.Threading.Timer class) instead of task in order to poll the memory usage on some specified interval.

Upvotes: 0

Jurgen Camilleri
Jurgen Camilleri

Reputation: 3589

I don't understand why you're complicating things. You can easily get the process's memory usage as follows:

int pid = your pid;
Process toMonitor = Process.GetProcessById(pid);
long memoryUsed = toMonitor.WorkingSet64;

This property returns the memory used up by pages in the working set in bytes.

Upvotes: 4

Related Questions