improve:优化timer

This commit is contained in:
2026-02-13 09:29:24 +08:00
parent a9fefadec9
commit 1d71f809cc
5 changed files with 93 additions and 47 deletions
+9 -8
View File
@@ -130,6 +130,7 @@ namespace Ink_Canvas.Helpers
#region Private Fields #region Private Fields
private Timer _unifiedPptTimer; private Timer _unifiedPptTimer;
private int _monitorTickCount; private int _monitorTickCount;
private volatile bool _unifiedPptTimerRunning;
private bool _isWpsMonitoringEnabled; private bool _isWpsMonitoringEnabled;
private Process _wpsProcess; private Process _wpsProcess;
@@ -179,10 +180,12 @@ namespace Ink_Canvas.Helpers
private void OnUnifiedPptTimerElapsed(object sender, ElapsedEventArgs e) private void OnUnifiedPptTimerElapsed(object sender, ElapsedEventArgs e)
{ {
if (_disposed || _isModuleUnloading) if (_disposed || _isModuleUnloading)
{
return; return;
}
if (_unifiedPptTimerRunning)
return;
_unifiedPptTimerRunning = true;
try try
{ {
var tick = Interlocked.Increment(ref _monitorTickCount); var tick = Interlocked.Increment(ref _monitorTickCount);
@@ -192,25 +195,23 @@ namespace Ink_Canvas.Helpers
if (IsConnected) if (IsConnected)
{ {
if (tick % 2 == 0) if (tick % 2 == 0)
{
CheckSlideShowState(); CheckSlideShowState();
}
if (_isWpsMonitoringEnabled && tick % 4 == 0) if (_isWpsMonitoringEnabled && tick % 4 == 0)
{
CheckWpsProcess(); CheckWpsProcess();
}
} }
if (tick >= int.MaxValue - 1000) if (tick >= int.MaxValue - 1000)
{
Interlocked.Exchange(ref _monitorTickCount, 0); Interlocked.Exchange(ref _monitorTickCount, 0);
}
} }
catch (Exception ex) catch (Exception ex)
{ {
LogHelper.WriteLogToFile($"统一PPT监控定时器执行失败: {ex}", LogHelper.LogType.Error); LogHelper.WriteLogToFile($"统一PPT监控定时器执行失败: {ex}", LogHelper.LogType.Error);
} }
finally
{
_unifiedPptTimerRunning = false;
}
} }
private void CheckAndConnectToPPT() private void CheckAndConnectToPPT()
+19 -16
View File
@@ -1,6 +1,7 @@
using Microsoft.Office.Interop.PowerPoint; using Microsoft.Office.Interop.PowerPoint;
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading;
using System.Timers; using System.Timers;
using System.Windows.Threading; using System.Windows.Threading;
using Application = System.Windows.Application; using Application = System.Windows.Application;
@@ -162,8 +163,8 @@ namespace Ink_Canvas.Helpers
// 唯一持久化的 COM 对象字段:PPT 应用程序实例 // 唯一持久化的 COM 对象字段:PPT 应用程序实例
private object _pptApplication; private object _pptApplication;
private Timer _connectionCheckTimer; private Timer _unifiedRotTimer;
private Timer _slideShowStateCheckTimer; private int _rotTickCount;
private bool _isModuleUnloading; private bool _isModuleUnloading;
private bool _lastSlideShowState; private bool _lastSlideShowState;
@@ -179,28 +180,32 @@ namespace Ink_Canvas.Helpers
private void InitializeTimers() private void InitializeTimers()
{ {
_connectionCheckTimer = new Timer(500); _unifiedRotTimer = new Timer(500);
_connectionCheckTimer.Elapsed += OnConnectionCheckTimerElapsed; _unifiedRotTimer.Elapsed += OnUnifiedRotTimerElapsed;
_connectionCheckTimer.AutoReset = true; _unifiedRotTimer.AutoReset = true;
}
_slideShowStateCheckTimer = new Timer(1000); private void OnUnifiedRotTimerElapsed(object sender, ElapsedEventArgs e)
_slideShowStateCheckTimer.Elapsed += OnSlideShowStateCheckTimerElapsed; {
_slideShowStateCheckTimer.AutoReset = true; var tick = Interlocked.Increment(ref _rotTickCount);
OnConnectionCheckTimerElapsed(sender, e);
if (tick % 2 == 0)
OnSlideShowStateCheckTimerElapsed(sender, e);
} }
public void StartMonitoring() public void StartMonitoring()
{ {
if (_disposed) return; if (_disposed) return;
_connectionCheckTimer?.Start(); _unifiedRotTimer?.Start();
_slideShowStateCheckTimer?.Start();
LogHelper.WriteLogToFile("[ROT] PPT 监控已启动", LogHelper.LogType.Trace); LogHelper.WriteLogToFile("[ROT] PPT 监控已启动", LogHelper.LogType.Trace);
} }
public void StopMonitoring() public void StopMonitoring()
{ {
_connectionCheckTimer?.Stop(); _unifiedRotTimer?.Stop();
_slideShowStateCheckTimer?.Stop();
DisconnectFromPPT(); DisconnectFromPPT();
LogHelper.WriteLogToFile("[ROT] PPT 监控已停止", LogHelper.LogType.Trace); LogHelper.WriteLogToFile("[ROT] PPT 监控已停止", LogHelper.LogType.Trace);
} }
@@ -364,8 +369,7 @@ namespace Ink_Canvas.Helpers
try try
{ {
_isModuleUnloading = true; _isModuleUnloading = true;
_connectionCheckTimer?.Stop(); _unifiedRotTimer?.Stop();
_slideShowStateCheckTimer?.Stop();
PPTConnectionChanged?.Invoke(false); PPTConnectionChanged?.Invoke(false);
LogHelper.WriteLogToFile("[ROT] 准备断开 PPT 连接,先卸载监控模块", LogHelper.LogType.Event); LogHelper.WriteLogToFile("[ROT] 准备断开 PPT 连接,先卸载监控模块", LogHelper.LogType.Event);
@@ -445,8 +449,7 @@ namespace Ink_Canvas.Helpers
System.Threading.Thread.Sleep(1000); System.Threading.Thread.Sleep(1000);
_isModuleUnloading = false; _isModuleUnloading = false;
_connectionCheckTimer?.Start(); _unifiedRotTimer?.Start();
_slideShowStateCheckTimer?.Start();
LogHelper.WriteLogToFile("[ROT] PPT 联动模块已重新进入联动状态", LogHelper.LogType.Trace); LogHelper.WriteLogToFile("[ROT] PPT 联动模块已重新进入联动状态", LogHelper.LogType.Trace);
} }
+54 -14
View File
@@ -1,5 +1,6 @@
using Ink_Canvas.Helpers; using Ink_Canvas.Helpers;
using System; using System;
using System.Runtime.InteropServices;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
@@ -7,6 +8,7 @@ using System.Windows.Controls.Primitives;
using System.Windows.Forms; using System.Windows.Forms;
using System.Windows.Ink; using System.Windows.Ink;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using System.Windows.Threading; using System.Windows.Threading;
@@ -19,17 +21,29 @@ namespace Ink_Canvas
{ {
public partial class MainWindow : Window public partial class MainWindow : Window
{ {
private const int WM_CLIPBOARDUPDATE = 0x031D;
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool AddClipboardFormatListener(IntPtr hwnd);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool RemoveClipboardFormatListener(IntPtr hwnd);
private bool isClipboardMonitoringEnabled; private bool isClipboardMonitoringEnabled;
private BitmapSource lastClipboardImage; private BitmapSource lastClipboardImage;
private HwndSource _clipboardHwndSource;
// 初始化剪贴板监控 // 初始化剪贴板监控
private void InitializeClipboardMonitoring() private void InitializeClipboardMonitoring()
{ {
try try
{ {
// 监听剪贴板变化
ClipboardNotification.ClipboardUpdate += OnClipboardUpdate; ClipboardNotification.ClipboardUpdate += OnClipboardUpdate;
isClipboardMonitoringEnabled = true; isClipboardMonitoringEnabled = true;
SourceInitialized += OnSourceInitializedForClipboard;
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -37,6 +51,36 @@ namespace Ink_Canvas
} }
} }
private void OnSourceInitializedForClipboard(object sender, EventArgs e)
{
SourceInitialized -= OnSourceInitializedForClipboard;
try
{
var handle = new WindowInteropHelper(this).Handle;
if (handle == IntPtr.Zero) return;
_clipboardHwndSource = HwndSource.FromHwnd(handle);
_clipboardHwndSource?.AddHook(ClipboardWndProc);
if (!AddClipboardFormatListener(handle))
LogHelper.WriteLogToFile($"AddClipboardFormatListener 失败: {Marshal.GetLastWin32Error()}", LogHelper.LogType.Warning);
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"安装剪贴板监听失败: {ex.Message}", LogHelper.LogType.Error);
}
}
private IntPtr ClipboardWndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == WM_CLIPBOARDUPDATE)
{
Dispatcher.BeginInvoke(new Action(() => ClipboardNotification.NotifyFromMessage()), DispatcherPriority.Background);
handled = true;
}
return IntPtr.Zero;
}
// 剪贴板内容变化事件处理 // 剪贴板内容变化事件处理
private void OnClipboardUpdate() private void OnClipboardUpdate()
{ {
@@ -273,6 +317,13 @@ namespace Ink_Canvas
ClipboardNotification.ClipboardUpdate -= OnClipboardUpdate; ClipboardNotification.ClipboardUpdate -= OnClipboardUpdate;
isClipboardMonitoringEnabled = false; isClipboardMonitoringEnabled = false;
} }
var handle = new WindowInteropHelper(this).Handle;
if (handle != IntPtr.Zero)
RemoveClipboardFormatListener(handle);
_clipboardHwndSource?.RemoveHook(ClipboardWndProc);
_clipboardHwndSource = null;
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -286,19 +337,10 @@ namespace Ink_Canvas
{ {
public static event Action ClipboardUpdate; public static event Action ClipboardUpdate;
private static Timer clipboardTimer;
private static string lastClipboardText = ""; private static string lastClipboardText = "";
private static bool lastHadImage; private static bool lastHadImage;
static ClipboardNotification() public static void NotifyFromMessage()
{
clipboardTimer = new Timer();
clipboardTimer.Interval = 500; // 每500ms检查一次
clipboardTimer.Tick += CheckClipboard;
clipboardTimer.Start();
}
private static void CheckClipboard(object sender, EventArgs e)
{ {
try try
{ {
@@ -320,8 +362,6 @@ namespace Ink_Canvas
public static void Stop() public static void Stop()
{ {
clipboardTimer?.Stop();
clipboardTimer?.Dispose();
} }
} }
} }
+2 -2
View File
@@ -2357,9 +2357,9 @@ namespace Ink_Canvas
private void StartOrStoptimerCheckAutoFold() private void StartOrStoptimerCheckAutoFold()
{ {
if (Settings.Automation.IsEnableAutoFold) if (Settings.Automation.IsEnableAutoFold)
timerCheckAutoFold.Start(); _unifiedMainWindowTimer?.Start();
else else
timerCheckAutoFold.Stop(); _unifiedMainWindowTimer?.Stop();
} }
private void ToggleSwitchAutoFoldInEasiNote_Toggled(object sender, RoutedEventArgs e) private void ToggleSwitchAutoFoldInEasiNote_Toggled(object sender, RoutedEventArgs e)
+9 -7
View File
@@ -57,9 +57,8 @@ namespace Ink_Canvas
public partial class MainWindow : Window public partial class MainWindow : Window
{ {
private Timer timerCheckPPT = new Timer();
private Timer timerKillProcess = new Timer(); private Timer timerKillProcess = new Timer();
private Timer timerCheckAutoFold = new Timer(); private Timer _unifiedMainWindowTimer;
private string AvailableLatestVersion; private string AvailableLatestVersion;
private Timer timerCheckAutoUpdateWithSilence = new Timer(); private Timer timerCheckAutoUpdateWithSilence = new Timer();
private Timer timerCheckAutoUpdateRetry = new Timer(); private Timer timerCheckAutoUpdateRetry = new Timer();
@@ -111,13 +110,11 @@ namespace Ink_Canvas
// 修改InitTimers方法中的初始时间和日期格式 // 修改InitTimers方法中的初始时间和日期格式
private void InitTimers() private void InitTimers()
{ {
// PPT检查现在由PPTManager处理,不再需要定时器
// timerCheckPPT.Elapsed += TimerCheckPPT_Elapsed;
// timerCheckPPT.Interval = 500;
timerKillProcess.Elapsed += TimerKillProcess_Elapsed; timerKillProcess.Elapsed += TimerKillProcess_Elapsed;
timerKillProcess.Interval = 2000; timerKillProcess.Interval = 2000;
timerCheckAutoFold.Elapsed += timerCheckAutoFold_Elapsed; _unifiedMainWindowTimer = new Timer(500);
timerCheckAutoFold.Interval = 500; _unifiedMainWindowTimer.Elapsed += OnUnifiedMainWindowTimerElapsed;
_unifiedMainWindowTimer.AutoReset = true;
timerCheckAutoUpdateWithSilence.Elapsed += timerCheckAutoUpdateWithSilence_Elapsed; timerCheckAutoUpdateWithSilence.Elapsed += timerCheckAutoUpdateWithSilence_Elapsed;
timerCheckAutoUpdateWithSilence.Interval = 1000 * 60 * 10; timerCheckAutoUpdateWithSilence.Interval = 1000 * 60 * 10;
timerCheckAutoUpdateRetry.Elapsed += timerCheckAutoUpdateRetry_Elapsed; timerCheckAutoUpdateRetry.Elapsed += timerCheckAutoUpdateRetry_Elapsed;
@@ -154,6 +151,11 @@ namespace Ink_Canvas
InitAutoSaveStrokesTimer(); InitAutoSaveStrokesTimer();
} }
private void OnUnifiedMainWindowTimerElapsed(object sender, ElapsedEventArgs e)
{
timerCheckAutoFold_Elapsed(sender, e);
}
// 初始化定时保存墨迹定时器 // 初始化定时保存墨迹定时器
private void InitAutoSaveStrokesTimer() private void InitAutoSaveStrokesTimer()
{ {