You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# .NET桌面开发中如何实现PC电池百分比变动时触发事件

实现方案

Windows系统本身未公开专门针对电池百分比变动的系统级事件,以下是两种稳定可行的实现方式:

方案1:轻量定时器轮询(推荐,实现最简单、稳定性最高)

该方案是业内通用的实现方式,低频率轮询对系统资源的消耗可以忽略,完全满足实时更新的需求:

实现步骤

  1. 把电池信息更新逻辑抽离为公共方法,增加变化校验避免无效UI重绘
// 缓存上一次的电量值,避免重复更新界面
private string _lastBatteryValue = string.Empty;

private void UpdateBatteryInfo()
{
    PowerStatus power = SystemInformation.PowerStatus;
    string currentValue;
    
    if (power.PowerLineStatus == PowerLineStatus.Online)
    {
        currentValue = "P";     
    }
    else if (power.PowerLineStatus == PowerLineStatus.Offline)
    {
        // 四舍五入取整,避免展示小数
        currentValue = $"{Math.Round(power.BatteryLifePercent * 100, 0)} %";
    }  
    else
    {
        currentValue = "未知";
    }

    // 仅当数值发生变化时才更新UI,减少不必要的渲染消耗
    if (currentValue != _lastBatteryValue)
    {
        BatteryPercentage = currentValue;
        _lastBatteryValue = currentValue;
    }
}
  1. 初始化UI线程定时器,定时触发更新(WinForms示例,WPF可改用DispatcherTimer)
private System.Windows.Forms.Timer _batteryMonitorTimer;

private void Form_Load(object sender, EventArgs e)
{
    // 绑定原有电源模式变更事件,处理插拔电的即时响应
    SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
    
    // 配置定时器,间隔可按需调整,1-10秒都属于合理范围,不会增加额外耗电
    _batteryMonitorTimer = new System.Windows.Forms.Timer
    {
        Interval = 3000 // 3秒更新一次
    };
    _batteryMonitorTimer.Tick += (s, args) => UpdateBatteryInfo();
    _batteryMonitorTimer.Start();
    
    // 启动时先获取一次初始电量
    UpdateBatteryInfo();
}
  1. 修复原有PowerModeChanged事件的跨线程问题,SystemEvents的事件默认在后台线程触发,直接更新UI会抛出异常:
void SystemEvents_PowerModeChanged(object sender, Microsoft.Win32.PowerModeChangedEventArgs e)
{
    // 切回UI线程执行更新操作
    if (this.InvokeRequired)
    {
        this.Invoke(new Action(UpdateBatteryInfo));
        return;
    }
    UpdateBatteryInfo();
}
  1. 资源释放,避免内存泄漏
private void Form_FormClosing(object sender, FormClosingEventArgs e)
{
    SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;
    _batteryMonitorTimer?.Stop();
    _batteryMonitorTimer?.Dispose();
}

方案2:封装自定义事件

如果要完全模拟事件触发的使用方式,可以在轮询逻辑的基础上封装自定义事件,当检测到电量变化时触发自定义的BatteryPercentageChanged事件,业务侧只需要订阅该事件即可,本质还是基于轮询实现,只是做了一层封装。


内容的提问来源于stack exchange,提问作者Taylor Abbott

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 15:21:03