[英]WPF Task Manager: Handling Refreshing CPU Load Value?
I am currently somewhat new to c#/wpf (and coding in general). 我目前对c#/ wpf(以及一般编码)有些新手。 I decided to start another project, being a custom made "task manager" of sorts.
我决定开始另一个项目,成为一个定制的“任务经理”。
(While I use binding, this is NOT a MVVM project, so all answers welcome) (虽然我使用绑定,但这不是MVVM项目,所以欢迎所有答案)
If you have ever opened task manager, you know that one of the main helpful tools it provides is a updating view of CPU/RAM/Whatever usage. 如果您曾经打开任务管理器,您知道它提供的主要有用工具之一是CPU / RAM /无论用法的更新视图。 Telling the user what percent of the resource they are using.
告诉用户他们正在使用的资源百分比。
My problem is not getting the CPU percentage. 我的问题是没有获得CPU百分比。 I am unsure on how to refresh the text property for CPU load in the UI efficiently.
我不确定如何有效地刷新UI中的CPU负载的文本属性。
My first thought was that I should create a Background worker (which is probably correct) to separate the thread loads. 我的第一个想法是我应该创建一个后台工作程序(可能是正确的)来分隔线程负载。 However, I can't seem to wrap my mind on the solution to implement the background workers in a useful way.
但是,我似乎无法将注意力集中在以有用的方式实现后台工作程序的解决方案上。
The code is currently set up in this fashion: 代码目前以这种方式设置:
Program loops (this is most likely the problem). 程序循环(这很可能是问题)。
private void Grid_Loaded(object sender, RoutedEventArgs e) { BgWrk = new BackgroundWorker(); BgWrk.DoWork += new DoWorkEventHandler(BackgroundWorker1_DoWork); BgWrk.RunWorkerAsync(); } private void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { while (true) { CpuInfoGrabber grabber = new CpuInfoGrabber(); Application.Current.Dispatcher.Invoke(new Action (() => Bnd.PerCpu = grabber.CpuPerUsed())); BgWrk.Dispose(); } }
Again the code works, but it is WAY to slow due to the load of retrieving all of that data. 代码再次起作用,但由于检索所有数据的负担,它的速度很慢。 Any suggestions on how to make this work well are appreciated!
任何关于如何使这项工作很好的建议值得赞赏!
Thanks 谢谢
Instead of looping you could use a timer to periodically poll for the CPU usage. 您可以使用计时器定期轮询CPU使用情况,而不是循环。
class Test
{
private System.Timers.Timer _timer;
public Test( )
{
_timer = new System.Timers.Timer
{
// Interval set to 1 millisecond.
Interval = 1,
AutoReset = true,
};
_timer.Elapsed += _timer_Elapsed;
_timer.Enabled = true;
_timer.Start( );
}
private void _timer_Elapsed( object sender, System.Timers.ElapsedEventArgs e )
{
// This handler is not executed on the gui thread so
// you'll have to marshal the call to the gui thread
// and then update your property.
var grabber = new CpuInfoGrabber();
var data = grabber.CpuPerUsed();
Application.Current.Dispatcher.Invoke( ( ) => Bnd.PerCpu = data );
}
}
I'd use Task.Run
instead of a BackgroundWorker
in your case: 在你的情况下我会使用
Task.Run
而不是BackgroundWorker
:
private void Grid_Loaded(object sender, RoutedEventArgs e)
{
//Keep it running for 5 minutes
CancellationTokenSource cts = new CancellationTokenSource(new TimeSpan(hours: 0, minutes: 5, seconds: 0));
//Keep it running until user closes the app
//CancellationTokenSource cts = new CancellationTokenSource();
//Go to a different thread
Task.Run(() =>
{
//Some dummy variable
long millisecondsSlept = 0;
//Make sure cancellation not requested
while (!cts.Token.IsCancellationRequested)
{
//Some heavy operation here
Thread.Sleep(500);
millisecondsSlept += 500;
//Update UI with the results of the heavy operation
Application.Current.Dispatcher.Invoke(() => txtCpu.Text = millisecondsSlept.ToString());
}
}, cts.Token);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.