[英]I have a thread.pool and how can i make Main Thread wait until all task are completed?
[英]How can i make a thread “report back” to main thread?
我正在制作一個應用程序,監視我的計算機上的東西,我想讓它更難以實現一個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%
?
謝謝
為了“回報”主線程,主線程必須是“監聽”。 這意味着,仍然在while循環中運行並檢查某種類型的隊列以查找代表報告的新項目。
您基本上需要的是一個隊列,其中工作線程將放置其報告,主線程將定期檢查此隊列以獲取來自該工作者的報告。
您有兩種主要方法:
如果您的應用程序是UI應用程序,則會自動獲得第一種方法,因為這是UI的工作方式。 要添加“項目”,您可以使用Control.BeginInvoke(在winforms中)或Dispatcher.BeginInvoke(在wpf中)。
你在那里使用的代碼啟動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++;
}
}
}
}
請改用計時器和事件。 這樣可以避免您的睡眠/忙碌等待。 如果多個線程可以同時修改靜態變量,也可以考慮使用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();
}
}
}
如果我找對你,這應該可以解決你的目的。 注意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++;
}
}
}
而不是cpuload++
嘗試使用
Interlocked.Increment(ref cpuload);
線程休眠3秒。 你在1之后中止它。去圖:)
通過回調,您可以做到這一點
這是一個例子:
public class Example2
{
// Declaration - Take 1 parameter, return nothing
public delegate void LogHandler(string message);
// Instantiation - Create a function which takes delegate as one parameter
// Verify if it is null before you use it
public void Process(LogHandler logHandler)
{
if (logHandler != null)
{
logHandler("Process() begin");
}
if (logHandler != null)
{
logHandler("Process() end");
}
}
}
public class Example2DelegateConsumer
{
// Create a method with the same signature as the delegate
static void Logger(string s)
{
Console.WriteLine(s);
}
public static void Main(string[] args)
{
Example2 ex2 = new Example2();
// Invocation in the client
Example2.LogHandler myLogger = new Example2.LogHandler(Logger);
ex2.Process(myLogger);
}
}
除了我在下面的原始(剽竊)答案之外,這種情況下你隨着時間的推移觀察一組值非常適合.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();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.