refactor: 项目稳定性优化
This commit is contained in:
@@ -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 是 int,GetLastInputInfo 是 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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user