長時間運行安防系統,導致CPU或內存利用率超80%,使得電腦變的緩慢、卡頓的問題。定時獲取CPU和內存利用率的數據,在不同時間段(如凌晨與平時),根據利用率的不同的閾值,進行:內存回收(70%)、重啟軟件(80%)、重啟電腦(90%&凌晨)等操作,以確保電腦和安防系統流暢;此功能可以在配置文件中選擇關閉(默認關閉)或開啟(根據情況手動開啟),利用率的閾值可配置,系統自檢頻率可配置
?
appsettings.json?配置文件
{"TimerTick": 0, // [系統自檢]頻率,單位:毫秒,(0為不檢查,60000一分鐘,300000五分鐘,600000十分鐘...)"ConfigTime": "1:00,3:00", //[系統自檢]可重啟電腦時間,時間從小到大,如 1:00,5:00 即:1點到5點之間,發生卡頓可重啟電腦"SwitchKey": "80,85,90", //[系統自檢]CPU&內存,利用率閾值,3個數字為一組,數字從小到大,如:80嚴重,85較嚴重,90非常嚴重...70,80,90...80,85,90...
}
MainForm.cs 程序文件
//獲取配置
public static int TimerTick = Tools.ToInt32(CustomConfigManager.GetConfig("TimerTick"), 0);
public static string ConfigTime = Tools.ToString(CustomConfigManager.GetConfig("ConfigTime"), "1:00,5:00");
public static string SwitchKey = Tools.ToString(CustomConfigManager.GetConfig("SwitchKey"), "80,85,90");private System.Windows.Forms.Timer timer3;//系統檢查//窗口加載
public void MainForm_Load(object sender, EventArgs e)
{if (TimerTick > 0){timer3 = new System.Windows.Forms.Timer();timer3.Interval = TimerTick;timer3.Tick += OnTimeTick3;timer3.Start();}
}//定時程序
private async void OnTimeTick3(object sender, EventArgs e)
{SYS_CHECK();
}//系統檢查
public async void SYS_CHECK()
{await Task.Run(() =>{float cpuUsage = GetCpuUsage();//cpu利用率float memoryUsage = GetMemoryUsage();//內存利用率 try{DateTime dt = DateTime.Now;//現在DateTime dt1 = Convert.ToDateTime(dt.ToString("yyyy-MM-dd 01:00:00"));//凌晨1點DateTime dt2 = Convert.ToDateTime(dt.ToString("yyyy-MM-dd 05:00:00"));//凌晨5點if (!string.IsNullOrWhiteSpace(ConfigTime)){string[] arr = ConfigTime.Split(',');if (arr.Length > 1){DateTime dTemp1 = dt1;DateTime dTemp2 = dt2;DateTime.TryParse(dt.ToString($"yyyy-MM-dd {arr[0]}"), out dTemp1);//凌晨1點DateTime.TryParse(dt.ToString($"yyyy-MM-dd {arr[1]}"), out dTemp2);//凌晨5點if (dTemp1 < dTemp2){dt1 = dTemp1;dt2 = dTemp2;}}}int minUsage = 80;//較嚴重int midUsage = 85;//挺嚴重int maxUsage = 90;//特嚴重string[] arrUsage = SwitchKey.Split(',');if (arrUsage.Length > 0 && arrUsage.Length > 2){arrUsage = arrUsage.OrderBy(a => a).ToArray();int.TryParse(arrUsage[0], out minUsage);//小int.TryParse(arrUsage[1], out midUsage);//中int.TryParse(arrUsage[2], out maxUsage);//大}if (dt > dt1 && dt < dt2)//凌晨{if (cpuUsage > midUsage || memoryUsage > midUsage)//85;//挺嚴重{shutdown();//...重啟電腦...}else if (cpuUsage > minUsage || memoryUsage > minUsage)//80;//較嚴重{restart();//...重啟程序...}}else//凌晨以外的時間(千萬別重啟電腦){if (cpuUsage > maxUsage || memoryUsage > maxUsage)//90;//特嚴重{restart();//...重啟程序...}else if (cpuUsage > midUsage || memoryUsage > midUsage)//85;//挺嚴重{GC_Collect();//...內存回收...}}}catch { }finally { }});
}//獲取CPU利用率
public float GetCpuUsage()
{try{using (PerformanceCounter cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total")){// 開始時間cpuCounter.NextValue();System.Threading.Thread.Sleep(2000); // 等待// 獲取CPU使用率float cpuUsage = cpuCounter.NextValue();//Console.WriteLine($"CPU Usage: {cpuUsage}%");//cpuLabel.Text = $"CPU 占用率: {cpuUsage:F2}%";return cpuUsage;}}catch{return 0;}
}//獲取內存利用率
public float GetMemoryUsage()
{try{using (var memoryCounter = new PerformanceCounter("Memory", "Available MBytes")){// 獲取可用內存(MB)float availableMemory = new PerformanceCounter("Memory", "Available MBytes").NextValue();// 獲取系統總物理內存(MB)long totalMemory = (long)new Microsoft.VisualBasic.Devices.ComputerInfo().TotalPhysicalMemory / (1024 * 1024);// 計算內存使用率float memoryUsage = (totalMemory - availableMemory) / totalMemory * 100;//memoryLabel.Text = $"內存占用率: {memoryUsage:F2}%";return memoryUsage;}}catch{return 0;}
}//重啟電腦
public void shutdown()
{//...重啟電腦...ProcessStartInfo psi = new ProcessStartInfo("shutdown", "/r /f /t 0");// 設置是否使用操作系統外殼程序啟動進程psi.UseShellExecute = false;// 創建一個新的進程并啟動它Process.Start(psi);
}//重啟軟件
public void restart()
{string executablePath = Application.ExecutablePath;//本程序路徑string arguments = "/skipLogin";//參數:跳過登錄Process.Start(executablePath, arguments);//開啟一個新的程序Application.Exit();//當前程序關閉退出
}//內存回收
public void GC_Collect()
{GC.Collect();GC.WaitForPendingFinalizers();GC.Collect();
}
Program.cs?程序入口文件
using Dm.filter;
using IntelligentSubstationCore.LightEquipment.LightControl;
using IntelligentSubstationCore.Security;namespace IntelligentSubstationCore
{internal static class Program{[STAThread]static void Main(string[] args){bool skipLogin = false;if (args.Length > 0 && args[0] == "/skipLogin"){skipLogin = true;}if (skipLogin){Application.Run(new AutoLogin());//自動登錄頁}else{Application.Run(new Login());//登錄頁面}}}
}
AutoLogin.cs?自動登錄?和?Login.cs?手動登錄(略)
說明:將之前登錄用戶的部分登錄信息(不包括賬號和密碼)保存到緩存中(如Redis),取出來驗證并自動登錄一下,并加載相關數據(AutoLogin.cs大部分代碼都在Login.cs里,一樣的都執行一遍),跳過登錄過程只有數據加載過程,無縫實現軟件重啟,釋放內存、緩存、Redis等...
如果模擬登錄AutoLogin.cs失敗(驗證失敗、登錄失敗、token失敗...),則強行進入登錄頁面Login.cs?重新登錄...
強行重啟電腦
? ProcessStartInfo psi = new ProcessStartInfo("shutdown", "/r /f /t 0");
是 C# 中用于啟動系統關機命令的代碼,其中的參數對應 Windows 系統的?
shutdown
?命令選項。以下是各參數的詳細說明:
shutdown
?命令基本語法plaintext
shutdown [/參數1] [/參數2] [...]
關鍵參數解析
1.?
/r
:重啟計算機
- 作用:執行重啟操作,等同于先關機再開機。
- 替代參數:
/s
:僅關機(不重啟)。/l
:注銷當前用戶(相當于 “退出登錄”)。2.?
/f
:強制關閉程序
- 作用:強制關閉所有未響應的應用程序,不顯示確認提示。
- 場景:當程序無響應或需要快速重啟時使用。
- 注意:可能導致未保存的數據丟失。
3.?
/t 0
:設置超時時間
/t
:指定執行操作前的等待秒數(超時時間)。0
:立即執行,無延遲。