我正在创建一个监视计算机上的内容的应用程序,我想让它更难以实现一个while循环。
所以我的问题是如果我想在一个单独的线程中获取cpu加载,如何更新类中的静态变量
namespace threads
{
class Program
{
static int cpuload = 0;
static void Main(string[] args)
{
while (true)
{
Thread th = new Thread(new ThreadStart(CheckCPULoad));
th.Start();
Thread.Sleep(1000); // sleep the main thread
th.Abort();
Console.WriteLine("load: {0}%", cpuload);
}
}
static void CheckCPULoad()
{
// things are updated every 3 secs, dummy data
Thread.Sleep(3000);
Random rnd = new Random();
cpuload++;// = rnd.Next(0, 100); // dummy data
}
}
}
因为每次都会打印“load:0%”。我需要修复什么才能让它显示
load: 0%
load: 0%
load: 0%
?
感谢
答案 0 :(得分:3)
为了“回报”主线程,主线程必须是“监听”。这意味着,仍然在while循环中运行并检查某种类型的队列以查找代表报告的新项目。
您基本上需要的是一个队列,其中工作线程将放置其报告,主线程将定期检查此队列以获取该工作人员的报告。
您有两种主要方法:
如果您的应用程序是UI应用程序,您将自动获得第一种方法,因为这是UI的工作方式。要添加“项目”,您可以使用Control.BeginInvoke(在winforms中)或Dispatcher.BeginInvoke(在wpf中)。
答案 1 :(得分:1)
你在那里使用的代码启动CheckCPULoad线程,等待1秒然后中止它。但是,CheckCPULoad线程做的第一件事就是睡3秒钟。所以你永远不会真正达到cpuload++
指令。我怀疑这会更接近你的意图:
namespace threads
{
class Program
{
static int cpuload = 0;
static void Main(string[] args)
{
Thread th = new Thread(new ThreadStart(CheckCPULoad));
th.Start();
while (true)
{
Thread.Sleep(1000);
Console.WriteLine("load: {0}%", cpuload);
}
th.Abort(); // Don't ever reach this line with while (true)
}
static void CheckCPULoad()
{
while (true)
{
Thread.Sleep(3000);
cpuload++;
}
}
}
}
答案 2 :(得分:1)
使用计时器和事件。这样可以避免您的睡眠/忙碌等待。如果多个线程可以同时修改静态变量,也可以考虑使用Interlocked.Increment。
using System;
using System.Threading;
using System.Timers;
using Timer = System.Timers.Timer;
namespace CpuLoad
{
internal class Program
{
private static int cpuload;
private static readonly AutoResetEvent autoEvent = new AutoResetEvent(false);
private static void Main(string[] args)
{
var timer = new Timer(3000);
timer.Elapsed += CheckCPULoad;
timer.Start();
while (true)
{
autoEvent.WaitOne();
autoEvent.Reset();
Console.WriteLine(cpuload);
}
}
private static void CheckCPULoad(object sender, ElapsedEventArgs e)
{
cpuload++;
autoEvent.Set();
}
}
}
答案 3 :(得分:1)
如果我找对你,这应该可以解决你的目的。注意CheckCPULoad()
方法中的while循环。
class Program
{
static int cpuload = 0;
static void Main(string[] args)
{
Thread th = new Thread(new ThreadStart(CheckCPULoad));
th.Start();
while (true)
{
Thread.Sleep(1000);
Console.WriteLine("load: {0}%", cpuload);
}
th.Abort(); // Don't ever reach this line with while (true)
}
static void CheckCPULoad()
{
while (true)
{
Thread.Sleep(3000);
cpuload++;
}
}
}
答案 4 :(得分:0)
而不是cpuload++
尝试使用
Interlocked.Increment(ref cpuload);
答案 5 :(得分:0)
线程休眠3秒。你在1之后中止它。去图:)
答案 6 :(得分:0)
使用callback即可
这是一个例子:
答案 7 :(得分:0)
除了我下面的原始(抄袭)答案之外,这种情况下你随着时间的推移观察一组值非常适合.NET的Reactive Extensions(http://blogs.msdn.com/ b / rxteam /)。您可以使用Rx获得所需的效果:
static void Main()
{
var cpuLoadSequence = Observable.GenerateWithTime(
0, // initial value
i => true, // continue forever
i => i + 1, // increment value
i => i, // result = value
i => TimeSpan.FromSeconds(3)); // delay 3 seconds
using (cpuLoadSequence.Subscribe(x => Console.WriteLine("load: {0}%", x)))
{
Console.WriteLine("Press ENTER to stop.");
Console.ReadLine();
}
}