Roland UA-25 ドライバ Windows10対応
C#でWindowsのCPU使用率を取得する方法
CPUの使用率をアプリに表示したいよね。 でも、マルチコアとかだと意外と面倒。 以下に、クラス化したので使ってください。
内部タイマーを使って、バッファをためます。 それを取得して使うだけ。
List<SingleCPUManager> SingleCPUList = new List<SingleCPUManager>(); // Initialize for (int i = 0; i<SingleCPUManager.GetCPUCount(); i++) { SingleCPUList.Add(new SingleCPUManager(i, 200, 4, 30)); } // Load Data int Ncpu = Environment.ProcessorCount; for (int k = 0; k<Ncpu; k++) { SingleCPUManager scpu = SingleCPUList[k]; float[] cpu_values = scpu.GetQueBuffer().ToArray(); }
using System; using System.Collections.Generic; using System.Diagnostics; namespace SimScreenSaver { /// <summary> /// CPUマネージャー /// </summary> public class SingleCPUManager { PerformanceCounter Counter; int BufferLength; public int CPUIndex; int Tap; List<float> QueBuffer; private System.Windows.Forms.Timer timer; /// <summary> /// コンストラクタ /// </summary> /// <param name="index">CPU番号</param> /// <param name="buffer_length">バッファ長さ</param> /// <param name="tap">移動平均tap</param> public SingleCPUManager(int index, int buffer_length, int tap, int interval_ms) { // Param this.BufferLength = buffer_length; this.CPUIndex = index; this.Tap = tap; if (this.Tap <= 0) this.Tap = 1; // Init Init(); // タイマーの間隔(ミリ秒) timer = new System.Windows.Forms.Timer(); timer.Interval = interval_ms; timer.Tick += Timer_Tick; timer.Start(); } private void Timer_Tick(object sender, EventArgs e) { Update(); } /// <summary> /// 初期化 /// </summary> /// <param name="index"></param> /// <param name="buffer_length"></param> void Init() { // CPUカウンタ Counter = new PerformanceCounter("Processor", "% Processor Time", CPUIndex.ToString()); // バッファ QueBuffer = new List<float>(); // バッファの初期化 for (int i = 0; i < BufferLength; i++) { QueBuffer.Add(0.0f); } } /// <summary> /// アップデート /// バッファにデータを追加 /// </summary> void Update() { float v = Counter.NextValue(); // 移動平均 float ave = 0; for (int i = 0; i < Tap - 1; i++) { ave += QueBuffer[(QueBuffer.Count - 1) - i]; } ave += v; ave /= Tap; v = ave; QueBuffer.Add(v); QueBuffer.RemoveAt(0); } /// <summary> /// バッファを渡す /// </summary> /// <returns></returns> public List<float> GetQueBuffer() { return QueBuffer; } /// <summary> /// Utilities /// </summary> /// <returns></returns> static public int GetCPUCount() { return Environment.ProcessorCount; } } }
C# グラフ描画
C#のGraphicsでグラフを書くことは良くある。 そのたびに、座標変換を書いていていよいよ面倒になったので、ここに記す。
/// <summary> /// 正規化座標へ変換 /// x[0,1], y[0,1]の範囲 /// </summary> /// <param name="Origins">ワールド座標の点</param> /// <param name="ClipRect">ワールド座標のクリップ領域. xy:左下. </param> static PointF Norm(PointF Origin, RectangleF ClipRect) { PointF NormPoint = new PointF(); NormPoint.X = (Origin.X - ClipRect.X) / (ClipRect.Width) + ClipRect.X; NormPoint.Y = (Origin.Y - ClipRect.Y) / (ClipRect.Height) + ClipRect.Y; return NormPoint; } /// <summary> /// 座標変換するぜ /// </summary> /// <param name="Origin"></param> /// <param name="ClipRect"></param> /// <param name="DrawRect"></param> static PointF ScreenPosition(PointF Origin, RectangleF ClipRect, RectangleF DrawRect) { PointF norm = Norm(Origin, ClipRect); PointF Screen = new PointF(); Screen.X = (norm.X * DrawRect.Width) + DrawRect.X; Screen.Y = ((1f - norm.Y) * DrawRect.Height) + DrawRect.Y; return Screen; } /// <summary> /// 指定した位置にラインを描画 /// </summary> /// <param name="e"></param> /// <param name="pen"></param> /// <param name="Origins">ワールド座標の点</param> /// <param name="ClipRect">ワールド座標のクリップ領域. xy:左下. </param> /// <param name="DrawRect">描画先のスクリーン座標. xy:左上</param> private void DrawLines(PaintEventArgs e, Pen pen, PointF[] Origins, RectangleF ClipRect, RectangleF DrawRect) { int N = Origins.Length; PointF[] ScrPoints = new PointF[N]; for (int i = 0; i < Origins.Length; i++) { PointF _ScrPoint = ScreenPosition(Origins[i], ClipRect, DrawRect); ScrPoints[i] = _ScrPoint; } e.Graphics.DrawLines(pen, ScrPoints); }