Skip to content

Commit bc0e14c

Browse files
committed
#28 修改后台线程下键盘钩子不生效的问题
1 parent e062392 commit bc0e14c

File tree

2 files changed

+91
-43
lines changed

2 files changed

+91
-43
lines changed
Lines changed: 90 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,114 @@
11
using System.Runtime.InteropServices;
2-
using System.Timers;
3-
using Timer = System.Timers.Timer;
2+
using System.Windows.Threading;
3+
using Dispatcher = System.Windows.Threading.Dispatcher;
44

5-
namespace ComputerLock.Platforms;
6-
7-
public class UserActivityMonitor
5+
namespace ComputerLock.Platforms
86
{
9-
private Timer? _timer;
10-
public EventHandler? OnIdle;
11-
private int _autoLockMillisecond;
12-
private readonly object _lock = new();
13-
14-
public void SetAutoLockSecond(int autoLockSecond)
7+
public class UserActivityMonitor : IDisposable
158
{
16-
lock (_lock)
9+
private readonly DispatcherTimer _timer;
10+
private int _autoLockMillisecond;
11+
private bool _isMonitoring;
12+
private readonly Dispatcher _dispatcher;
13+
private bool _disposed;
14+
15+
public event EventHandler? OnIdle;
16+
17+
public UserActivityMonitor()
1718
{
18-
_autoLockMillisecond = autoLockSecond * 1000;
19+
_dispatcher = Dispatcher.CurrentDispatcher;
20+
21+
_timer = new DispatcherTimer(TimeSpan.FromSeconds(1), DispatcherPriority.Normal, Timer_Tick, _dispatcher);
22+
_timer.Start();
1923
}
20-
}
2124

22-
public void StartMonitoring()
23-
{
24-
lock (_lock)
25+
public void SetAutoLockSecond(int autoLockSecond)
26+
{
27+
RunOnUIThread(() =>
28+
{
29+
_autoLockMillisecond = autoLockSecond * 1000;
30+
});
31+
}
32+
33+
public void StartMonitoring()
34+
{
35+
RunOnUIThread(() =>
36+
{
37+
_isMonitoring = true;
38+
});
39+
}
40+
41+
public void StopMonitoring()
42+
{
43+
RunOnUIThread(() =>
44+
{
45+
_isMonitoring = false;
46+
});
47+
}
48+
49+
private void Timer_Tick(object? sender, EventArgs e)
2550
{
26-
if (_timer == null)
51+
if (!_isMonitoring || _disposed)
2752
{
28-
_timer = new Timer();
29-
_timer.Interval = 1000;
30-
_timer.Elapsed += Timer_Elapsed;
53+
return;
54+
}
55+
56+
var lastInputInfo = new WinApi.LastInputInfo();
57+
lastInputInfo.cbSize = (uint)Marshal.SizeOf(lastInputInfo);
58+
59+
if (WinApi.GetLastInputInfo(ref lastInputInfo))
60+
{
61+
long elapsedMillisecond = Environment.TickCount64 - lastInputInfo.dwTime;
62+
if (elapsedMillisecond > _autoLockMillisecond)
63+
{
64+
OnIdle?.Invoke(this, EventArgs.Empty);
65+
// 触发一次后停止监控
66+
StopMonitoring();
67+
}
3168
}
32-
_timer.Start();
3369
}
34-
}
3570

36-
public void StopMonitoring()
37-
{
38-
lock (_lock)
71+
private void RunOnUIThread(Action action)
3972
{
40-
if (_timer != null)
73+
if (_disposed)
74+
{
75+
return;
76+
}
77+
78+
if (_dispatcher.CheckAccess())
4179
{
42-
_timer.Elapsed -= Timer_Elapsed;
43-
_timer.Stop();
44-
_timer.Dispose();
45-
_timer = null;
80+
action();
81+
}
82+
else
83+
{
84+
_dispatcher.Invoke(action);
4685
}
4786
}
48-
}
4987

50-
private void Timer_Elapsed(object? sender, ElapsedEventArgs e)
51-
{
52-
var lastInputInfo = new WinApi.LastInputInfo();
53-
lastInputInfo.cbSize = (uint)Marshal.SizeOf(lastInputInfo);
88+
public void Dispose()
89+
{
90+
Dispose(true);
91+
GC.SuppressFinalize(this);
92+
}
5493

55-
if (WinApi.GetLastInputInfo(ref lastInputInfo))
94+
protected virtual void Dispose(bool disposing)
5695
{
57-
long elapsedMillisecond = Environment.TickCount64 - lastInputInfo.dwTime;
58-
if (elapsedMillisecond > _autoLockMillisecond)
96+
if (_disposed)
97+
{
98+
return;
99+
}
100+
101+
if (disposing)
59102
{
60-
OnIdle?.Invoke(this, EventArgs.Empty);
103+
RunOnUIThread(() =>
104+
{
105+
_timer.Stop();
106+
_timer.Tick -= Timer_Tick;
107+
});
61108

62-
// 避免死锁,异步停止监控
63-
Task.Run(StopMonitoring);
109+
OnIdle = null;
64110
}
111+
_disposed = true;
65112
}
66113
}
67-
}
114+
}

src/ComputerLock/Services/GlobalLockService.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ private void SystemUnlock()
302302

303303
public void Dispose()
304304
{
305+
_activityMonitor.Dispose();
305306
_hotkeyHook.Dispose();
306307
SystemEvents.SessionSwitch -= SystemEvents_SessionSwitch;
307308
}

0 commit comments

Comments
 (0)