refactor: 项目稳定性优化

This commit is contained in:
2026-01-17 17:00:15 +08:00
parent 7abd445039
commit c276e9e2b9
7 changed files with 135 additions and 110 deletions

View File

@@ -1,5 +1,7 @@
using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Windows.Media.Control;
namespace TimerApp
@@ -26,22 +28,17 @@ namespace TimerApp
/// <returns></returns>
public static long GetIdleTime()
{
LASTINPUTINFO lastInputInfo = new LASTINPUTINFO();
lastInputInfo.cbSize = (uint)Marshal.SizeOf(lastInputInfo);
lastInputInfo.dwTime = 0;
LASTINPUTINFO lastInputInfo = new LASTINPUTINFO
{
cbSize = (uint)Marshal.SizeOf<LASTINPUTINFO>(),
dwTime = 0
};
if (GetLastInputInfo(ref lastInputInfo))
{
// Environment.TickCount 可能会在大约 24.9 天后翻转为负数,
// 但 GetLastInputInfo 返回的也是 uint (DWORD),所以我们统一转为 long 处理差值
// 或者直接使用 unchecked 减法处理溢出
// 更稳健的做法是使用 GetTickCount64 (Vista+),但 Environment.TickCount 在 .NET Core 3.1+ 已经是 64位了(Environment.TickCount64)
// 这里为了兼容性,我们简单处理。注意 GetLastInputInfo 返回的是 uint 毫秒数。
long envTicks = Environment.TickCount;
// 处理 TickCount 翻转问题 (Environment.TickCount 是 intGetLastInputInfo 是 uint)
// 简单的做法:
return (long)GetTickCount() - (long)lastInputInfo.dwTime;
uint tickCount = GetTickCount();
uint idleMs = unchecked(tickCount - lastInputInfo.dwTime);
return idleMs;
}
return 0;
@@ -56,27 +53,57 @@ namespace TimerApp
/// <returns>如果有媒体正在播放返回 true否则返回 false</returns>
public static bool IsMediaPlaying()
{
try
{
var sessionManager = GlobalSystemMediaTransportControlsSessionManager.RequestAsync().GetAwaiter().GetResult();
var sessions = sessionManager.GetSessions();
EnsureMediaPlaybackStatusFresh();
return Volatile.Read(ref _mediaPlaying);
}
foreach (var session in sessions)
private static bool _mediaPlaying;
private static long _mediaLastUpdateMs = -1;
private static int _mediaUpdateInProgress;
private static void EnsureMediaPlaybackStatusFresh()
{
long now = Environment.TickCount64;
long last = Interlocked.Read(ref _mediaLastUpdateMs);
if (last >= 0 && now - last < 3000)
{
return;
}
if (Interlocked.Exchange(ref _mediaUpdateInProgress, 1) == 1)
{
return;
}
_ = Task.Run(async () =>
{
bool playing = false;
try
{
var playbackInfo = session.GetPlaybackInfo();
if (playbackInfo.PlaybackStatus == GlobalSystemMediaTransportControlsSessionPlaybackStatus.Playing)
var sessionManager = await GlobalSystemMediaTransportControlsSessionManager.RequestAsync();
var sessions = sessionManager.GetSessions();
foreach (var session in sessions)
{
return true;
var playbackInfo = session.GetPlaybackInfo();
if (playbackInfo.PlaybackStatus == GlobalSystemMediaTransportControlsSessionPlaybackStatus.Playing)
{
playing = true;
break;
}
}
}
}
catch
{
// 如果 API 调用失败,返回 false保守处理
return false;
}
return false;
catch
{
playing = false;
}
finally
{
Volatile.Write(ref _mediaPlaying, playing);
Interlocked.Exchange(ref _mediaLastUpdateMs, Environment.TickCount64);
Interlocked.Exchange(ref _mediaUpdateInProgress, 0);
}
});
}
}
}