Hi all..
I am having some problems with my code.
I need a textbox to update the CPU current speed. Only problem is that
the form itself freezes when I use a normal timer.
The timer updates every 500 ms...
How else should I attack this problem?
//Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Management;
using Microsoft.Win32;
namespace HardwareMonitor
{
public partial class SystemMonitor : Form
{
ManagementObject MO = new ManagementObject("Win32_processor.DeviceID='CPU0'");
delegate void DelegateUpdate();
public SystemMonitor()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//CPU Name
string CPUName = (string)(MO["Name"]);
txtCPUName.Text = CPUName;
}
private void timer1_Tick(object sender, EventArgs e)
{
DelegateUpdate delegat = new DelegateUpdate ( () =>
{
//CPU speed using WMI. Win32_processor.DeviceID
uint speed = (uint)(MO["CurrentClockSpeed"]);
txtCurrentSpeed.Text = Convert.ToString(speed) + " MHz";
//CPU Core Voltage
UInt16 CurrentVoltageRaw = (UInt16)(MO["CurrentVoltage"]);
//Devide the voltage by 10 to get the real value
double CurrentVoltage = Convert.ToDouble(CurrentVoltageRaw);
CurrentVoltage /= 10;
txtCoreVoltage.Text = Convert.ToString(CurrentVoltage) + " V";
MO.Dispose();
});
txtCoreVoltage.Invoke(delegat);
txtCurrentSpeed.Invoke(delegat);
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
timer1.Enabled = false;
Close();
}
private void btnCheck_Click(object sender, EventArgs e)
{
timer1.Enabled = true;
}
}
}
Loading
Sam HobbsPosted May 23, 2011, 2:55 PM
I have attached my project. Does this work the way you want it to?
Sam HobbsPosted May 23, 2011, 8:53 PM
I am sure there are many ways to do this and the documentation is sparse. Try the attached; it is a bit simpler than a version using BackgroundWorker. Yes, I know that the InvokeRequired stuff is confusing; I hope you can understand it well enough.
John LarsenPosted May 23, 2011, 4:55 PM
I have attached my code in a zip file..
John LarsenPosted May 23, 2011, 4:46 PM
Just figured out something why it freezes for me.
The timer is running, that I can see, but I think the problem I have is because I run
ManagementObject MO = new ManagementObject("Win32_processor.DeviceID='CPU0'") every time the timer ticks.
I have to do this otherwise the CurrentClockSpeed will not update, only stick with the initial value.
Initiating a new ManagementObject seems to take too long.
Anyone know a way around this?
John-O
John LarsenPosted May 23, 2011, 4:15 PM
This is so strange.. This was pretty similar to what I originally had.
But your code for some reason is working..
Thank you so much..
John-O
John LarsenPosted May 23, 2011, 2:30 PM
I think it is strange that it worked for you but not for me..
I am using C# express... Does that have anything to do with it?
Sam HobbsPosted May 22, 2011, 8:48 PM
John LarsenPosted May 22, 2011, 6:16 AM
I tried the example with Application.DoEvents();
It work better but it is not perfect. Still hangs a little and will not make the program float any good.
Is it better to use backgroundworker?
How does that work? *Searching Google as I type*
John-Ove Larsen
John LarsenPosted May 22, 2011, 5:57 AM
Sam.. I tried it again just as a quick test..
This does however freeze the form.
I have not tried the other yet, but I will try that as well.
Here is the short code for testing.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Management;
namespace CPUClockTesting
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
timer1.Enabled = false;
Close();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
timer1.Enabled = true;
}
private void timer1_Tick(object sender, EventArgs e)
{
ManagementObject MO = new ManagementObject("Win32_processor.DeviceID='CPU0'");
uint Speed = (uint)(MO["CurrentClockSpeed"]);
textBox1.Text = Convert.ToString(Speed);
}
}
}
Sam HobbsPosted May 22, 2011, 1:47 AM
You do not need to use delegates in the timer1_Tick event.
You do not need to MO.Dispose(). In fact, your program works the way you had it as you posted here, except without the Dispose. Avoid using Dispose in C#; don't use it unless you know you need to and especially when you know you still need the object without creating another one.
I tested your code and it worked after I commented out the Dispose. It still worked when I did not use a delegate.
Posted May 21, 2011, 10:56 PM
private void timer1_Tick(object sender, EventArgs e)
{
Application.DoEvents();
DelegateUpdate delegat = new DelegateUpdate ( () =>
{
//CPU speed using WMI. Win32_processor.DeviceID
uint speed = (uint)(MO["CurrentClockSpeed"]);
txtCurrentSpeed.Text = Convert.ToString(speed) + " MHz";
//CPU Core Voltage
UInt16 CurrentVoltageRaw = (UInt16)(MO["CurrentVoltage"]);
//Devide the voltage by 10 to get the real value
double CurrentVoltage = Convert.ToDouble(CurrentVoltageRaw);
CurrentVoltage /= 10;
txtCoreVoltage.Text = Convert.ToString(CurrentVoltage) + " V";
MO.Dispose();
});
Application.DoEvents();
txtCoreVoltage.Invoke(delegat);
Application.DoEvents();
txtCurrentSpeed.Invoke(delegat);
Application.DoEvents();
}
Later you can remove the unwanted Application.DoEvents(); methods.
Hope this helps you.
Posted May 21, 2011, 10:39 PM
MastermosleyPosted May 21, 2011, 8:55 PM