Control the CPU Utilization during Application Execution written C#.Net

A

apondu

Hi,

This is Govardhan, i am working on C#.Net.

I have a problem and i am sure most of them would have come across
this

problem. I have written a application in C#.Net. It does lot of work
so i know

it'll take time for the execution. But my problem is it starts
utilizing 98 to

100% of the CPU. I needed to know is there any way where in i can
control the

amount of CPU utilization for my application and restrict it to use
say some 60

-70% of the CPU. Actually when it starts utilizing 98 to 100% of the
CPU, i get

a feel that my system is hung-up, so i wanted to avoid this.

Is there any other solution to this problem.

If someone knows the solution for this problem then can u share it.

I am waiting for the response, this is my mail-id (e-mail address removed)

Thanks for the help and suggestions.

Regards,
Govardhana.
 
R

Rob Conklin

Your question is a very broad one. The extent to which a program written in
most any language will "hog" the cpu depends on many factors: the way your
program structures the way it processes the task(s) that it is doing, the
way the operating system handles process scheduling, and also the
archetecture of the computer system your program is running on -- the dual
core type processors, (Intel Core Duo & AMD Dual Core, etc), are must less
vulnerable to getting bogged done by applications that bring single CPU
systems to their knees).

Anyway, from an application development point of view, the important thing
is to make an analysis of your big hoggy task and attempt to find a way to
structure it so that it is ammenable to running
a little bit at a time. Here is an illustration of how one MIGHT want to
approach this, in a very simple way...

since you are using an object-oriented language...

encapsulate the big task in an object, with these methods, (at least)
doSomeWork(); // does an atomic / small part of the job.
..JobDone // property to find out from worker if its done with task
DoAbort(); // when called will do any needed tidy up of object before it
is destroyed, and will set
// flag to indicate to caller that it has received request
to abort and successfully
// cleaned up any needed allocated memory and tied up any
loose ends..

..refCount; // property that increments everytime doSomeWork() is called

The object (in this design) also has to maintain information about it's
'state'. It stops and starts working on the
job, so it has to know where to pick up again when it resumes the task. It
also needs to know how to figure out
when it is done.

the following little C# program demonstrates how to flesh out a poor man's
approach to management of a hoggy process using the Application.DoEvents()
method to yield control back
to the system on a periodic basis so that other application GUI and other
applications currently running
are not choked by your task's execution...

Note: by calling DoEvents(), the concern about actual CPU utilization is
reduced, but If you want to literally reduce overall CPU utilization, you
can add calls to System.Threading.Thread.Sleep() just after the call to
DoEvents (see below).

// not included, the designer code...SO, to run this, create a new window's
program then add two buttons,
// button1 is start button, button2 is abort button....
// put these to the bottom right part of the form -- this program outputs a
string near the top and needs that area.
// attach "button1_Click" [starts task, implemented, below] to button1, and
"button2_Click" [
// [aborts task ... also below] to button2 via the Properties->Events
editors for button1 and button2's Click events.

// ASLO, you need a StatusBar (from the VS toolbox Menus and ToolBars
section)
// and a toolstripProgress bar -- this is added to the StatusBar with the
little do-hicky / drop-down at that appears
// on the left side of the embedded StatusBar at design time,(click the down
area and pick a progress bar).

// Lastly, replace the entire content of the Form1.cs file with this:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
toolStripProgressBar1.Maximum = 100;
toolStripProgressBar1.Minimum = 0;
toolStripProgressBar1.Value = 0;
}

private void button1_Click(object sender, EventArgs e)
{
RunHoggyProcess();
}

public void RunHoggyProcess()
{
// AlphabetPrinter class
// prints one char in the range [A..Z] each time each time its
DoSomeWork() method is called, keeps track of the
// next character to print (in the sequence of the alphabet) so
that next call to DoSomeWork prints the next char in the alphabet.
// also demonstrates aborting and progress reporting...resource
cleanup, etc..

AlphabetPrinter myPrinter = new AlphabetPrinter(this);


while (myPrinter.JobDone == false)
{
myPrinter.DoSomeWork();

// you can call DoEvents several times if desired, and add
calls to System.Threading.Thread.Sleep if you really which to lower your
// applications reported CPU utilization...You can also set
your applications priority as a running task (can't remember now, ask,
// I can look that up later...it does not work as well as
one might hope, but can be tweaked with some additional coding...

Application.DoEvents();


if (gUserClickedAbortButton)
{
if (myPrinter.DoAbort() == false) // luckily for
us, DoAbort always returns true in this implementation.
throw new Exception();
}

UpdateBar(myPrinter.refCount);
}
}

private bool gUserClickedAbortButton = false;

private void button2_Click(object sender, EventArgs e)
{
gUserClickedAbortButton = true;
}

private void UpdateBar(int iteration)
{
int totalJobSize = Convert.ToInt32('z') - Convert.ToInt32('a');
double donePcnt = (double)iteration / (double)totalJobSize;
if (donePcnt > 1.0) donePcnt = 1.0;
try
{
// exception happy control is best put in a try catch block,
lazy version here...
toolStripProgressBar1.Value = (int) (donePcnt * 100.0);
} catch{}

}


}


// AlphabetPrinter class
// prints one char in the range [A..Z] each time each time its
DoSomeWork() method is called, keeps track of the
// next character to print (in the sequence of the alphabet) so
that next call to DoSomeWork prints the next char in the alphabet.
// also demonstrates aborting and progress reporting...resource
cleanup, etc..

public class AlphabetPrinter
{
// these first two members could be used in any similar
implementation...
int gCalledNTimes = 0;
bool gDoneYet = false;

// key important state data
int gCurrentChar; // currrent letter in alphabet to
print.
int gCurrentX = 5; // output X position on Graphics surface
for next print job.

// passed in constructor for output of the letters
Form gCallersForm;

char gStartChar = 'A'; // the start and end of english
alphabet
char gEndChar = 'Z';

// GDI+ resources we need to initialize AND cleanup (GDI+ objects
are not auto-garbage collected).
Graphics g;
Font gMyFont;
SolidBrush gSB;

public AlphabetPrinter(Form chalkBoard)
{
// initialize our drawing surface and drawing objects...

gCurrentChar = Convert.ToInt32(gStartChar);

gCallersForm = chalkBoard;
g = Graphics.FromHwnd(gCallersForm.Handle);
gMyFont = new Font("Courier", 12.0F, FontStyle.Regular);
gSB = new SolidBrush(Color.FromArgb(0, 0, 0));

}

// querry to determine progress of the worker (N time called is
reported, and if caller knows more about task, can compute
// % of task complete...
public int refCount
{
get
{
return gCalledNTimes;
}
}

public bool JobDone
{
get
{
if (gDoneYet)
{
// clean up if finished...
if (gSB != null) gSB.Dispose();
if (gMyFont != null) gMyFont.Dispose();
if (g != null) g.Dispose();
}

return gDoneYet;
}
}

// print the next character in the alphabet using GDI+ DrawString()
public void DoSomeWork()
{
float yPos = 25f;

String txtOut = Convert.ToChar(gCurrentChar).ToString();


g.DrawString(txtOut, gMyFont, gSB, new PointF(gCurrentX,
yPos)); // gSB is a solidBrush created in ctor()

gCurrentX += (int)(g.MeasureString(txtOut, gMyFont).Width);
// call GDI+ function to calc size of any particular char in a

// font specified to update
output position.

// update object's 'state'
gCurrentChar++;
gCalledNTimes++;


// test to see if job is 'done'
if (gCurrentChar > Convert.ToInt32(gEndChar))
gDoneYet = true;
}

public bool DoAbort()
{
if (gSB != null) gSB.Dispose();
if (gMyFont != null) gMyFont.Dispose();
if (g != null) g.Dispose();

return true;
}

}





}



Something like this is implemented as a component (BackgroundWorker, on the
components tab of the toolbox), available to add to projects in Visual
Studio.

It's a bit clutzy to use, but probably internally more sophisticated in
approach than this implementation using
DoEvents() to yield to the system .... I thought this might be useful just
to provide a more general and transparent
illustration of how one might structure any long running hoggy process so
that it works and plays well with the
system.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top