@@ -9,6 +9,66 @@ namespace CarinaStudio.Threading;
9
9
/// </summary>
10
10
public class DispatcherSynchronizationContext : SynchronizationContext
11
11
{
12
+ // Stub of delayed call-back.
13
+ class DelayedCallbackStub : IDelayedCallbackStub
14
+ {
15
+ // Fields.
16
+ readonly Action ? actionCallback ;
17
+ public readonly Dispatcher Dispatcher ;
18
+ volatile bool isCancellable = true ;
19
+ volatile bool isCancelled ;
20
+ readonly DispatcherPriority priority ;
21
+ readonly SendOrPostCallback ? sendOrPostCallback ;
22
+ readonly object ? state ;
23
+
24
+ // Constructor.
25
+ public DelayedCallbackStub ( Dispatcher dispatcher , Action action , DispatcherPriority priority )
26
+ {
27
+ this . actionCallback = action ;
28
+ this . Dispatcher = dispatcher ;
29
+ this . priority = priority ;
30
+ }
31
+ public DelayedCallbackStub ( Dispatcher dispatcher , SendOrPostCallback callback , object ? state , DispatcherPriority priority )
32
+ {
33
+ this . Dispatcher = dispatcher ;
34
+ this . priority = priority ;
35
+ this . sendOrPostCallback = callback ;
36
+ this . state = state ;
37
+ }
38
+
39
+ /// <inheritdoc/>
40
+ void IDelayedCallbackStub . Callback ( ) =>
41
+ this . Dispatcher . Post ( this . CallbackEntry , this . priority ) ;
42
+
43
+ // Entry of call-back.
44
+ void CallbackEntry ( )
45
+ {
46
+ lock ( this )
47
+ {
48
+ if ( this . isCancelled )
49
+ return ;
50
+ this . isCancellable = false ;
51
+ }
52
+ if ( this . actionCallback is not null )
53
+ this . actionCallback ( ) ;
54
+ else if ( this . sendOrPostCallback is not null )
55
+ this . sendOrPostCallback ( this . state ) ;
56
+ }
57
+
58
+ /// <inheritdoc/>
59
+ bool IDelayedCallbackStub . Cancel ( )
60
+ {
61
+ lock ( this )
62
+ {
63
+ if ( this . isCancelled || ! this . isCancellable )
64
+ return false ;
65
+ this . isCancelled = true ;
66
+ }
67
+ return true ;
68
+ }
69
+ }
70
+
71
+
12
72
// Static fields.
13
73
static volatile DispatcherSynchronizationContext ? UIThreadInstance ;
14
74
@@ -25,6 +85,23 @@ public DispatcherSynchronizationContext(Dispatcher dispatcher)
25
85
{
26
86
this . dispatcher = dispatcher ;
27
87
}
88
+
89
+
90
+ /// <summary>
91
+ /// Cancel posted delayed call-back.
92
+ /// </summary>
93
+ /// <param name="token">Token returned from <see cref="PostDelayed(SendOrPostCallback, object?, DispatcherPriority, int)"/> or <see cref="PostDelayed(Action, DispatcherPriority, int)"/>.</param>
94
+ /// <returns>True if call-back cancelled successfully.</returns>
95
+ public bool CancelDelayed ( object token )
96
+ {
97
+ if ( ! DelayedCallbacks . TryGetCallbackStub ( token , out var callbackStub )
98
+ || callbackStub is not DelayedCallbackStub delayedCallbackStub
99
+ || delayedCallbackStub . Dispatcher != this . dispatcher )
100
+ {
101
+ return false ;
102
+ }
103
+ return DelayedCallbacks . Cancel ( token ) ;
104
+ }
28
105
29
106
30
107
/// <summary>
@@ -76,6 +153,29 @@ public void Post(SendOrPostCallback d, object? state, DispatcherPriority priorit
76
153
/// <param name="priority">Priority.</param>
77
154
public void Post ( Action action , DispatcherPriority priority ) =>
78
155
this . dispatcher . Post ( action , priority ) ;
156
+
157
+
158
+ /// <summary>
159
+ /// Post delayed call-back.
160
+ /// </summary>
161
+ /// <param name="callback">Call-back.</param>
162
+ /// <param name="priority">Priority.</param>
163
+ /// <param name="delayMillis">Delayed time in milliseconds.</param>
164
+ /// <returns>Token of posted delayed call-back.</returns>
165
+ public object PostDelayed ( Action callback , DispatcherPriority priority , int delayMillis ) =>
166
+ DelayedCallbacks . Schedule ( new DelayedCallbackStub ( this . dispatcher , callback , priority ) , delayMillis ) ;
167
+
168
+
169
+ /// <summary>
170
+ /// Post delayed call-back.
171
+ /// </summary>
172
+ /// <param name="callback">Call-back.</param>
173
+ /// <param name="state">Custom state pass to call-back.</param>
174
+ /// <param name="priority">Priority.</param>
175
+ /// <param name="delayMillis">Delayed time in milliseconds.</param>
176
+ /// <returns>Token of posted delayed call-back.</returns>
177
+ public object PostDelayed ( SendOrPostCallback callback , object ? state , DispatcherPriority priority , int delayMillis ) =>
178
+ DelayedCallbacks . Schedule ( new DelayedCallbackStub ( this . dispatcher , callback , state , priority ) , delayMillis ) ;
79
179
80
180
81
181
/// <inheritdoc/>
0 commit comments