feat: 处理系统恢复以重置媒体检测

This commit is contained in:
2026-01-19 09:58:12 +08:00
parent 78c07a12d0
commit fe47293da5
2 changed files with 32 additions and 1 deletions

View File

@@ -2,6 +2,7 @@ using System;
using System.Drawing; using System.Drawing;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Windows.Forms; using System.Windows.Forms;
using Microsoft.Win32;
namespace TimerApp namespace TimerApp
{ {
@@ -129,6 +130,8 @@ namespace TimerApp
_monitor.Start(); _monitor.Start();
SystemEvents.PowerModeChanged += OnPowerModeChanged;
// Set tray icon // Set tray icon
try try
{ {
@@ -550,6 +553,7 @@ namespace TimerApp
} }
else else
{ {
SystemEvents.PowerModeChanged -= OnPowerModeChanged;
notifyIcon1.Visible = false; notifyIcon1.Visible = false;
notifyIcon1.Dispose(); notifyIcon1.Dispose();
} }
@@ -615,5 +619,15 @@ namespace TimerApp
{ {
this.WindowState = FormWindowState.Minimized; this.WindowState = FormWindowState.Minimized;
} }
private void OnPowerModeChanged(object sender, PowerModeChangedEventArgs e)
{
if (e.Mode == PowerModes.Resume)
{
// 系统唤醒时,强制重置媒体播放检测状态,
// 避免因检测线程挂起导致一直误报“正在播放”而无法进入工作状态。
NativeMethods.InvalidateMediaCache();
}
}
} }
} }

View File

@@ -57,6 +57,18 @@ namespace TimerApp
return Volatile.Read(ref _mediaPlaying); return Volatile.Read(ref _mediaPlaying);
} }
/// <summary>
/// 强制失效媒体播放状态缓存
/// </summary>
public static void InvalidateMediaCache()
{
Interlocked.Exchange(ref _mediaLastUpdateMs, -1);
// 不直接重置 _mediaPlaying以免在检测过程中出现闪烁
// 只是强制下一次 IsMediaPlaying 触发新的检测。
// 但如果处于 Resume 状态,假设不播放是安全的。
Volatile.Write(ref _mediaPlaying, false);
}
private static bool _mediaPlaying; private static bool _mediaPlaying;
private static long _mediaLastUpdateMs = -1; private static long _mediaLastUpdateMs = -1;
private static int _mediaUpdateInProgress; private static int _mediaUpdateInProgress;
@@ -256,7 +268,12 @@ namespace TimerApp
thread.IsBackground = true; thread.IsBackground = true;
thread.SetApartmentState(ApartmentState.STA); thread.SetApartmentState(ApartmentState.STA);
thread.Start(); thread.Start();
thread.Join();
// Wait with timeout (e.g. 2 seconds) to prevent hanging
if (!thread.Join(2000))
{
return false;
}
if (error is not null) if (error is not null)
{ {