1- using AsyncFiberWorks . Core ;
2- using AsyncFiberWorks . Threading ;
3- using System ;
1+ using System ;
42using System . Threading ;
53
64namespace AsyncFiberWorks . Windows . Timer
75{
86 /// <summary>
9- /// Timer using WaitableTimerEx in Windows.
10- /// This timer starts a dedicated thread.
7+ /// Sleep implements using WaitableTimerEx in Windows.
118 /// </summary>
12- public class OneshotWaitableTimerEx : IOneshotTimer , IDisposable
9+ public class WaitableTimerSleeper : IDisposable
1310 {
14- readonly ConsumerThread _thread ;
1511 readonly WaitableTimerEx _waitableTimer ;
1612 readonly ManualResetEventSlim _resetEvent = new ManualResetEventSlim ( ) ;
1713 WaitHandle [ ] _waitHandles = null ;
18- Action < object > _copiedAction ;
19- object _state ;
2014 int _scheduled = 0 ;
2115 bool _disposed = false ;
2216
@@ -25,20 +19,17 @@ public class OneshotWaitableTimerEx : IOneshotTimer, IDisposable
2519 /// <summary>
2620 /// Create a timer.
2721 /// </summary>
28- public OneshotWaitableTimerEx ( )
22+ public WaitableTimerSleeper ( )
2923 {
30- _thread = ConsumerThread . StartNew ( ) ;
3124 _waitableTimer = new WaitableTimerEx ( manualReset : false ) ;
3225 }
3326
3427 /// <summary>
35- /// Start a timer .
28+ /// Sleep .
3629 /// </summary>
37- /// <param name="action">The process to be called when the timer expires.</param>
38- /// <param name="state">Arguments passed when that callback is invoked.</param>
3930 /// <param name="firstIntervalMs">Timer wait time. Must be greater than or equal to 0.</param>
4031 /// <param name="token">A handle to cancel the timer.</param>
41- public void InternalSchedule ( Action < object > action , object state , int firstIntervalMs , CancellationToken token = default )
32+ public void Sleep ( int firstIntervalMs , CancellationToken token = default )
4233 {
4334 if ( firstIntervalMs < 0 )
4435 {
@@ -53,48 +44,29 @@ public void InternalSchedule(Action<object> action, object state, int firstInter
5344 }
5445 if ( _scheduled > 0 )
5546 {
56- _resetEvent . Set ( ) ;
47+ throw new InvalidOperationException ( $ "Already called." ) ;
5748 }
5849 _scheduled += 1 ;
59- _copiedAction = action ;
60- _state = state ;
50+ _resetEvent . Reset ( ) ;
51+ SetWaitHandles ( token ) ;
52+ }
6153
62- _thread . Enqueue ( ( ) =>
54+ _waitableTimer . Set ( firstIntervalMs * - 10000L ) ;
55+ int index = WaitHandle . WaitAny ( _waitHandles ) ;
56+ if ( index == 0 )
57+ {
58+ lock ( _lockObj )
6359 {
64- lock ( _lockObj )
65- {
66- if ( _scheduled > 1 )
67- {
68- _scheduled -= 1 ;
69- return ;
70- }
71- if ( _disposed )
72- {
73- return ;
74- }
75- _resetEvent . Reset ( ) ;
76- SetWaitHandles ( token ) ;
77- }
78-
79- _waitableTimer . Set ( firstIntervalMs * - 10000L ) ;
80- int index = WaitHandle . WaitAny ( _waitHandles ) ;
81- if ( index == 0 )
82- {
83- lock ( _lockObj )
84- {
85- _scheduled -= 1 ;
86- _copiedAction ( _state ) ;
87- }
88- }
89- else
90- {
91- _waitableTimer . Cancel ( ) ;
92- lock ( _lockObj )
93- {
94- _scheduled -= 1 ;
95- }
96- }
97- } ) ;
60+ _scheduled -= 1 ;
61+ }
62+ }
63+ else
64+ {
65+ _waitableTimer . Cancel ( ) ;
66+ lock ( _lockObj )
67+ {
68+ _scheduled -= 1 ;
69+ }
9870 }
9971 }
10072
@@ -127,7 +99,6 @@ void DisposeResources()
12799 {
128100 _waitableTimer . Dispose ( ) ;
129101 _resetEvent . Dispose ( ) ;
130- _thread . Dispose ( ) ;
131102 _waitHandles = null ;
132103 }
133104
@@ -144,8 +115,8 @@ public void Dispose()
144115 }
145116 _disposed = true ;
146117 _resetEvent . Set ( ) ;
147- _thread . Enqueue ( DisposeResources ) ;
148118 }
119+ DisposeResources ( ) ;
149120 }
150121 }
151122}
0 commit comments