Mefhisto1
Mefhisto1

Reputation: 2228

Asynchronously collecting CPU usage data (working in the background)

I'm trying to let the user decide when to start collecting CPU usage, via a button click. While working in the background, application gets total cpu usage every second, and stops doing so only with a different event, which is a click from a different button. I have a slight problem. I can't get the app to stop, when I change the state of the application via the button click:

class CPUPerformanceMonitor
{
    PerformanceCounter cpuCounter;
    List<float> cpuUsage;
    private delegate void start();
    start sc;
    IAsyncResult iftar;
    MeasureState currState;

    public CPUPerformanceMonitor()
    {
        cpuCounter = new PerformanceCounter();
        cpuUsage = new List<float>();
        sc = new start(StartMeasuring);
        currState = MeasureState.Measuring;

        cpuCounter.CategoryName = "Processor";
        cpuCounter.CounterName = "% Processor Time";
        cpuCounter.InstanceName = "_Total";


    }

    public void Start()
    {
        currState = MeasureState.Measuring;

        iftar = sc.BeginInvoke(null, null);

            if (currState == MeasureState.NotMeasuring)
            {
                sc.EndInvoke(iftar);
            }

    }

    private void StartMeasuring()
    {
        cpuUsage.Add(cpuCounter.NextValue());
        Thread.Sleep(1000);

    // if (currState != MeasureState.NotMeasuring)
    // {
                StartMeasuring();
    // }
    }

    public void Stop()
    {
        currState = MeasureState.NotMeasuring;
    }
}

So when the user clicks the start button, Start methods fires off, which calls different method asynchronously. When the user clicks stop button state should change to "NotMeasuring" which should end the method invocation. However this does not work. Is it because of the recursive call to the StartMeasuring method? I tried adding a check if the current state is Measuring and then recursively call the method again. That way it worked. It's commented out in the code.

Upvotes: 0

Views: 204

Answers (1)

Servy
Servy

Reputation: 203824

If you want to do something every second, the immediate solution should be to use a Timer. And indeed in your case this is an entirely appropriate tool for the job. It will be much easier to work with and more efficient than what you have. Create a time when constructing the object, start the timer on the button click, and stop the timer on the other button click. It will make all of the code very strightforward to work with.

Upvotes: 5

Related Questions