All people who are working on any version of the Windows operating system know about Task Manager. They might be using it very frequently to start, end or manage processes. Task Manager has been around for a long time and is commonly used in our daily work. However, it is still lacking some features which might be useful in certain situations. So, I designed this application to provide features which are not present in the built-in Windows Task Manager. This application was created in VS.NET 2003 using C# and Windows Forms.
In this article, I will first explain some features present in the application, and then I will discuss its design and coding.
Task Manager features
- Displays all processes running in your system
- Allows you to add and remove any process (task) on your local machine
- Highlights current executing processes
- Enables connection to any machine and displays its process list
- Allows you to set or get the priority of any process running on your local machine
- Enables monitoring of .NET CLR managed memory
Creating the application
First, create a new Windows Application in VS.NET 2003 using C# and name it
CustomizedTaskManager. Then design the main start-up form as shown below:
I placed a tab control with two tab pages. One is used to display Task Manager and the other to display CLR memory statistics. Then I placed a
ListView control on first tab page where all processes and their details are displayed. I added columns like "process name," "process id," etc. to the
ListView. Then I added
MainMenu to provide following options:
- To popup "Connect to remote machine" dialog
- To popup "Create new task window"
- To control highlighting of currently executing processes
- To end a selected process
- To exit the application
Add a performance counter component from toolbox and set its
.NET CLR Memory and its
aspnet_wp. You can keep
instanceName as the first 15 characters in any .NET-managed application's name. Add appropriate labels to
tabpage2 as shown in the figure:
Then add another form, naming it
frmnewprcdetails, and design it as shown:
To minimize coding, I am using this form both to display dialog for connecting to a remote machine and to add new task functionality. These are the namespaces I used in
Initially, I thought of displaying all processes in
ListView and updating their details every second using the
Threading.Timer object. However, if we update like that for every second by clearing all
ListView items and reloading with new details, it will produce a flicker on the form for every reload. So, in order to avoid that problem, I used a hash table. The logic is outlined in the following section.
All processes are loaded when the form loads. I've created a timer object with a one second interval to call
LoadAllProcesses(). In this method, first I am storing all currently running process' details in a hash table using
Process.GetProcesses(machinename). Then I am comparing the hash table contents with each item present in
ListView and if its process ID matches in both the hash table and
ListView then we will update its details (i.e. processor time, number of threads) and set the
ListView item's color to red if its processor time or memory usage is changed.
If any new process is created, then the count of the
HashTable items will not be equal. Based on this condition, I am adding an item to the
ListView control from the hash table's contents whose process ID is not present in the
If any process has ended, then I am removing that item from
ListView by using the ended process' ID. We can get the ended process' ID by finding the items that are present in
ListView but not in the current process list (hash table).
In this way, it will update all process details in the
ListView control every second without any flicker. In order to create a new task, I am getting the user-selected task's path via the
frmnewprcdetails form. We will create that process by calling
Then I am providing functionality to end selected processes by calling
In order to load a remote machine's process list, you must have administrative rights or equivalent on that remote machine. I am providing a remote machine's process load by setting
mcname to the selected machine's IP address from the "Connect to remote machine" dialog. After getting the IP address, I am reloading
ListView with the remote machine's process list.
We can get and set the priority of any running process from the context menu control. In the context menu, Set Priority will first make a check mark on the correct
MenuItem based on its priority. After the context menu pops up, we can change its priority by clicking the appropriate
MenuItem. In the status bar, I am displaying the total count of processes and threads in each panel.
tabpage2 I am displaying CLR memory details such as heap size. Some applications won't run fast if their objects are not garbage-collected properly. This will help us to see the total heap size and what the share percentage is between Gen 0, Gen 1, and Gen 2 objects. This will help us to know whether our application is running slow because of insufficient CLR memory. This will also help us make the decision of whether or not to call Garbage Collector explicitly in our application code.
I've added the features "Always on top" and "Hide when minimized" to the Options menu. I've also added
NotifyIcon to show/hide Task Manager.
The final output will look something like this:
We can still enhance this application by providing more performance counters for processors, ASP.NET applications, good UIs, etc. Please see the article download for further reference. I hope this code will be useful to all.
- May 9, 2007 - Original version posted