This article only describes some precautions in the program. The performancecounter in. Net accounts for the main part. If you are interested, you can download the source code for reference.
Directory
- And download
- Brief Introduction to performance monitoring concepts in windows and. net
- Use performancecounter in. net
- Mvvm: bind an icommand set
- Thread-safe observablecollection
- About Charts
Returned directory
And download
Note: The program works well in my Windows 7 environment, but it is not tested in Windows XP.
Download the program or source code
Click to download
(This is an archive of Microsoft SkyDrive. Please download it directly in your browser. Some download tools may not be available for download)
Program environment:. NET Framework 4.0 client profile
Source code environment: Visual C #2010 express SP1
Returned directory
Brief Introduction to performance monitoring concepts in windows and. net
The Performance Monitor in Windows can provide some real-time running information of software and hardware. The performance monitor related to network monitoring belongs to the network interface class, in the program, bytes received ED/sec and Bytes Sent/sec counters (Counter) are used to obtain the number of bytes received and sent by the corresponding NIC (which can be approximately equal to the number of downloads and uploads ), the instance in the monitor class is the interface of the known NIC (some may be virtual NICs, not all physical hardware NICS ).
These three concepts are very important. For example, to query the number of threads of an operating system process, the performance monitor class is process, and the counter name is threadcount in the process class, the instance is the process name. Of course, some performance monitoring classes may also have no instances.
You can open the Performance Monitor in Control Panel-Administrative Tools. Or enter perfmon (Performance Monitor)
(: Add counters to Windows Performance Monitor)
. NET provides packaging for the Windows performance monitor. The corresponding types are in the system. Diagnostics namespace and in system. dll (no additional reference is required ).
The "Performance Monitor type" and "performance counter name" in the Performance Monitor directly correspond to the performancecountercategory and performancecounter classes under system. diagnostics. The instance name of the Performance Monitor can be obtained from the getinstancenames method of performancecountercategory.
Returned directory
Use performancecounter in. net
The performancecounter in. NET provides good API packaging and is very convenient to use.
First, create the fields to be used (including the performancecounter object and the monitor name to be used ):
Const string network = "Network Interface ";
Const string Recv = "bytes encoded ED/sec ";
Const string sent = "bytes sent/sec ";
Performancecountercategory category;
Next, make some judgments. If the system cannot find the corresponding monitoring counter, an exception is thrown. If yes, create a cececountercategory.
If (! Performancecountercategory. exists (network)
|! Performancecountercategory. counterexists (Recv, Network)
|! Performancecountercategory. counterexists (sent, network ))
{
Throw new invalidoperationexception ("your system has no performance monitoring metrics ");
}
Category = new performancecountercategory (network );
Then, how do I get the system Nic name? As mentioned above, call the getinstancenames method of performancecountercategory to return a string array.
Category. getinstancenames ();
Finally, the monitoring is executed. we store the obtained data in a custom eventargs:
Class nicdataeventargs: eventargs
{
// Receive byte
Public float Recv {Get; private set ;}
// Send byte
Public float sent {Get; private set ;}
Public nicdataeventargs (float Recv, float sent)
{
Recv = Recv;
Sent = sent;
}
}
Run the Code:
Public event eventhandler <nicdataeventargs> Update;
Protected virtual void onupdate (nicdataeventargs ARGs)
{
If (update! = NULL)
Update (this, argS );
}
Public void start (string INS)
{
Initialize ();
// Create two performancecounter to monitor the receipt and sending respectively.
VaR crecv = new performancecounter (Network, Recv, INS );
VaR csent = new performancecounter (Network, sent, INS );
While (true)
{
// Obtain the next value
VaR valrecv = crecv. nextvalue ();
VaR valsent = csent. nextvalue ();
// Send event data
Onupdate (New nicdataeventargs (valrecv, valsent ));
// Wait 1 second
System. Threading. thread. Sleep (1000 );
}
}
Note: In the while loop above, there is a statement in the current thread waiting for one second. According to the suggestions of Microsoft's Bcl team, it is best to wait 1 second or longer for the next value of a performancecounter, because the next value of some performancecounter requires the previous value, if the performancecounter is called continuously in a short period of time. nextvalue () may make the two values the same, resulting in unpredictable results.
Reference connection: http://blogs.msdn.com/ B /bclteam/archive/2006/06/02/618156.aspx
Note: The above code is slightly different from the actual code of the program in order to explain it, but the overall logic remains unchanged.
Returned directory
Mvvm: bind an icommand set
Mvvm is really a very surprising mode. The execution buttons in the program come from a command set. The command objects in WPF come from the icommand object. We use relaycommand and add the text attribute, similar to routeduicommand. text attributes. Then add the commands to the collection, and bind the command set to the interface.
(Relaycommand from: http://msdn.microsoft.com/en-us/magazine/dd419663.aspx)
The command set is generated as follows:
Readonlycollection <icommand> _ commands;
Public readonlycollection <icommand> commands
{
Get
{
If (_ commands = NULL)
{
_ Commands = new readonlycollection <icommand> (
New List <icommand> ()
{
New relaycommandwithtext (OBJ => Start (), OBJ =>! Isstarted & validatedata () {text = ""},
New relaycommandwithtext (OBJ => stop (), OBJ => isstarted) {text = "stop "},
New relaycommandwithtext (OBJ => refresh () {text = "Refresh network device "}
});
}
Return _ commands;
}
}
The ListBox command is directly bound to the interface:
<ListBox itemssource = "{binding commands }"
Focusable = "false">
<ListBox. itemtemplate>
<Datatemplate>
<Button command = "{binding}" content = "{binding text }"
Margin = "5" minwidth = "60"/>
</Datatemplate>
</ListBox. itemtemplate>
</ListBox>
So the three buttons of the program appear, and when isenabled should be set to true, and when it should be set to false all work well (thanks to icommand. canexecute event), don't you think it's amazing?
Returned directory
Thread-safe observablecollection
The method used by the main viewmodel to receive data is called by another thread, so this thread cannot modify the observablecollection, because this action will trigger updates on the main interface, and one WPF dispatcher can only follow one thread. Of course, using dispatcher. begininvoke/invoke can solve the problem, but sometimes a thread-safe observablecollection may seem more comfortable ......
The program uses a generic class called safeobservable (inheriting ilist <t> and inotifycollectionchanged), which comes from here: http://www.deanchalk.me.uk/post/Thread-Safe-Dispatcher-Safe-Observable-Collection-for-WPF.aspx
Returned directory
About Charts
Chart controls from the WPF toolkit open source framework (http://wpf.codeplex.com /)
System must be referenced to create a chart. windows. controls. datavisualization. toolkit. DLL, the program directly put the system. windows. controls. datavisualization. toolkit. DLL and wpftoolkit. the DLL is directly copied to the local directory and referenced. Therefore, you can run the tool without installing the WPF toolkit.