feat: 优化异常处理,新增日志记录
This commit is contained in:
@@ -19,6 +19,12 @@ namespace TimerApp
|
||||
private bool _isPaused;
|
||||
private bool _disposed;
|
||||
|
||||
// 状态检测缓存
|
||||
private int _checkTickCounter;
|
||||
private const int CheckIntervalTicks = 3; // 每3秒检查一次空闲/媒体状态
|
||||
private long _cachedIdleMs;
|
||||
private bool _cachedMediaPlaying;
|
||||
|
||||
// 配置 (默认值)
|
||||
public TimeSpan WorkDuration { get; set; } = TimeSpan.FromMinutes(20);
|
||||
public TimeSpan RestDuration { get; set; } = TimeSpan.FromMinutes(1);
|
||||
@@ -45,6 +51,8 @@ namespace TimerApp
|
||||
|
||||
public void Start()
|
||||
{
|
||||
// 启动时立即触发一次检测
|
||||
_checkTickCounter = CheckIntervalTicks;
|
||||
_timer.Start();
|
||||
ResetWork();
|
||||
}
|
||||
@@ -70,6 +78,8 @@ namespace TimerApp
|
||||
}
|
||||
|
||||
private void Timer_Tick(object? sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 如果处于暂停状态,不处理计时逻辑
|
||||
if (_isPaused)
|
||||
@@ -77,8 +87,21 @@ namespace TimerApp
|
||||
return;
|
||||
}
|
||||
|
||||
long idleMs = NativeMethods.GetIdleTime();
|
||||
TimeSpan idleTime = TimeSpan.FromMilliseconds(idleMs);
|
||||
long idleMs;
|
||||
TimeSpan idleTime;
|
||||
|
||||
// 优化:降低系统API调用频率
|
||||
// 每 CheckIntervalTicks (3) 秒更新一次状态
|
||||
_checkTickCounter++;
|
||||
if (_checkTickCounter >= CheckIntervalTicks)
|
||||
{
|
||||
_checkTickCounter = 0;
|
||||
_cachedIdleMs = NativeMethods.GetIdleTime();
|
||||
_cachedMediaPlaying = NativeMethods.IsMediaPlaying();
|
||||
}
|
||||
|
||||
idleMs = _cachedIdleMs;
|
||||
idleTime = TimeSpan.FromMilliseconds(idleMs);
|
||||
|
||||
if (CurrentState == MonitorState.Resting)
|
||||
{
|
||||
@@ -102,8 +125,8 @@ namespace TimerApp
|
||||
}
|
||||
else
|
||||
{
|
||||
// 检测是否有视频/媒体正在播放
|
||||
bool isMediaPlaying = NativeMethods.IsMediaPlaying();
|
||||
// 使用缓存的媒体播放状态
|
||||
bool isMediaPlaying = _cachedMediaPlaying;
|
||||
|
||||
// 工作/空闲模式逻辑
|
||||
if (idleTime > IdleThreshold || isMediaPlaying)
|
||||
@@ -163,6 +186,11 @@ namespace TimerApp
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError("Error in ActivityMonitor Timer_Tick", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void RefreshStatus()
|
||||
{
|
||||
|
||||
36
Logger.cs
Normal file
36
Logger.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace TimerApp
|
||||
{
|
||||
public static class Logger
|
||||
{
|
||||
private static readonly string LogFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "error.log");
|
||||
private static readonly object LockObj = new object();
|
||||
|
||||
public static void LogError(string message, Exception? ex = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
lock (LockObj)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] ERROR: {message}");
|
||||
if (ex != null)
|
||||
{
|
||||
sb.AppendLine($"Exception: {ex.Message}");
|
||||
sb.AppendLine($"StackTrace: {ex.StackTrace}");
|
||||
}
|
||||
sb.AppendLine(new string('-', 50));
|
||||
|
||||
File.AppendAllText(LogFile, sb.ToString());
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Failed to log, nothing we can do
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
27
Program.cs
27
Program.cs
@@ -8,12 +8,19 @@ static class Program
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
// 设置全局异常处理
|
||||
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
|
||||
Application.ThreadException += Application_ThreadException;
|
||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
||||
|
||||
if (!SingleInstanceManager.TryAcquire(out var instance) || instance is null)
|
||||
{
|
||||
SingleInstanceManager.SignalExistingInstance();
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using (instance)
|
||||
{
|
||||
TaskbarIntegration.InitializeProcess();
|
||||
@@ -25,4 +32,24 @@ static class Program
|
||||
Application.Run(mainForm);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.LogError("Fatal error in Main", ex);
|
||||
MessageBox.Show($"程序发生严重错误即将退出:\n{ex.Message}", "TimerApp Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
|
||||
{
|
||||
Logger.LogError("Unhandled UI Exception", e.Exception);
|
||||
// 这里可以选择不退出,或者提示用户
|
||||
// MessageBox.Show("发生未知错误,程序将尝试继续运行。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
}
|
||||
|
||||
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||
{
|
||||
var ex = e.ExceptionObject as Exception;
|
||||
Logger.LogError("Unhandled Domain Exception" + (e.IsTerminating ? " (Terminating)" : ""), ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user