@@ -75,6 +75,31 @@ public async Task TaskQueued()
7575 await ResumeHelper . Await ( ref _taskQueued ) ;
7676 ResumeHelper . Clear ( ref _taskQueued ) ;
7777 }
78+
79+ /// <summary>
80+ /// Resumes only when a specific task with a given delay
81+ /// has been queued up.
82+ /// </summary>
83+ /// <param name="dueTime">The due time of the task that should be present.</param>
84+ /// <returns>The task to await</returns>
85+ public async Task TaskQueued ( long dueTime )
86+ {
87+ for ( ; ; )
88+ {
89+ lock ( _queue )
90+ {
91+ foreach ( var t in _queue . Values )
92+ {
93+ if ( t . DueTime == dueTime )
94+ {
95+ return ;
96+ }
97+ }
98+ }
99+
100+ await TaskQueued ( ) ;
101+ }
102+ }
78103
79104 /// <summary>
80105 /// Advance the virtual time by the given amount and
@@ -136,10 +161,11 @@ private void Enqueue(TaskTask task)
136161 /// </summary>
137162 /// <param name="error">The error to signal</param>
138163 /// <param name="delayMillis">The time to delay this task.</param>
164+ /// <param name="absolute">Should the <paramref name="delayMillis"/> be interpreted as absolute time?</param>
139165 /// <returns>The task to await</returns>
140- public Task CreateErrorTask ( Exception error , long delayMillis = 0L )
166+ public Task CreateErrorTask ( Exception error , long delayMillis = 0L , bool absolute = false )
141167 {
142- var now = Volatile . Read ( ref _now ) + delayMillis ;
168+ var now = ( absolute ? 0L : Volatile . Read ( ref _now ) ) + delayMillis ;
143169 var tcs = new TaskCompletionSource < bool > ( ) ;
144170 Enqueue ( new ErrorTaskTask < bool > ( now , tcs , error ) ) ;
145171 return tcs . Task ;
@@ -152,10 +178,11 @@ public Task CreateErrorTask(Exception error, long delayMillis = 0L)
152178 /// </summary>
153179 /// <param name="error">The error to signal</param>
154180 /// <param name="delayMillis">The time to delay this task.</param>
181+ /// <param name="absolute">Should the <paramref name="delayMillis"/> be interpreted as absolute time?</param>
155182 /// <returns>The task to await</returns>
156- public Task < T > CreateErrorTask < T > ( Exception error , long delayMillis = 0L )
183+ public Task < T > CreateErrorTask < T > ( Exception error , long delayMillis = 0L , bool absolute = false )
157184 {
158- var now = Volatile . Read ( ref _now ) + delayMillis ;
185+ var now = ( absolute ? 0L : Volatile . Read ( ref _now ) ) + delayMillis ;
159186 var tcs = new TaskCompletionSource < T > ( ) ;
160187 Enqueue ( new ErrorTaskTask < T > ( now , tcs , error ) ) ;
161188 return tcs . Task ;
@@ -166,10 +193,11 @@ public Task<T> CreateErrorTask<T>(Exception error, long delayMillis = 0L)
166193 /// after the specified virtual time elapses
167194 /// </summary>
168195 /// <param name="delayMillis">The time to delay this task.</param>
196+ /// <param name="absolute">Should the <paramref name="delayMillis"/> be interpreted as absolute time?</param>
169197 /// <returns>The task to await</returns>
170- public Task CreateCompleteTask ( long delayMillis = 0L )
198+ public Task CreateCompleteTask ( long delayMillis = 0L , bool absolute = false )
171199 {
172- var now = Volatile . Read ( ref _now ) + delayMillis ;
200+ var now = ( absolute ? 0L : Volatile . Read ( ref _now ) ) + delayMillis ;
173201 var tcs = new TaskCompletionSource < bool > ( ) ;
174202 Enqueue ( new ValueTaskTask < bool > ( now , tcs , true ) ) ;
175203 return tcs . Task ;
@@ -183,10 +211,11 @@ public Task CreateCompleteTask(long delayMillis = 0L)
183211 /// <typeparam name="T">The value type.</typeparam>
184212 /// <param name="item">The item to signal as the result.</param>
185213 /// <param name="delayMillis">The time to delay this task.</param>
214+ /// <param name="absolute">Should the <paramref name="delayMillis"/> be interpreted as absolute time?</param>
186215 /// <returns>The task to await</returns>
187- public Task < T > CreateValueTask < T > ( T item , long delayMillis = 0L )
216+ public Task < T > CreateValueTask < T > ( T item , long delayMillis = 0L , bool absolute = false )
188217 {
189- var now = Volatile . Read ( ref _now ) + delayMillis ;
218+ var now = ( absolute ? 0L : Volatile . Read ( ref _now ) ) + delayMillis ;
190219 var tcs = new TaskCompletionSource < T > ( ) ;
191220 Enqueue ( new ValueTaskTask < T > ( now , tcs , item ) ) ;
192221 return tcs . Task ;
@@ -197,10 +226,11 @@ public Task<T> CreateValueTask<T>(T item, long delayMillis = 0L)
197226 /// the specified virtual time elapses.
198227 /// </summary>
199228 /// <param name="delayMillis">The time to delay this task.</param>
229+ /// <param name="absolute">Should the <paramref name="delayMillis"/> be interpreted as absolute time?</param>
200230 /// <returns>The task to await</returns>
201- public Task CreateCancelTask ( long delayMillis = 0L )
231+ public Task CreateCancelTask ( long delayMillis = 0L , bool absolute = false )
202232 {
203- var now = Volatile . Read ( ref _now ) + delayMillis ;
233+ var now = ( absolute ? 0L : Volatile . Read ( ref _now ) ) + delayMillis ;
204234 var tcs = new TaskCompletionSource < bool > ( ) ;
205235 Enqueue ( new CanceledTaskTask < bool > ( now , tcs ) ) ;
206236 return tcs . Task ;
@@ -212,10 +242,11 @@ public Task CreateCancelTask(long delayMillis = 0L)
212242 /// </summary>
213243 /// <typeparam name="T">The value type.</typeparam>
214244 /// <param name="delayMillis">The time to delay this task.</param>
245+ /// <param name="absolute">Should the <paramref name="delayMillis"/> be interpreted as absolute time?</param>
215246 /// <returns>The task to await</returns>
216- public Task < T > CreateCancelTask < T > ( long delayMillis = 0L )
247+ public Task < T > CreateCancelTask < T > ( long delayMillis = 0L , bool absolute = false )
217248 {
218- var now = Volatile . Read ( ref _now ) + delayMillis ;
249+ var now = ( absolute ? 0L : Volatile . Read ( ref _now ) ) + delayMillis ;
219250 var tcs = new TaskCompletionSource < T > ( ) ;
220251 Enqueue ( new CanceledTaskTask < T > ( now , tcs ) ) ;
221252 return tcs . Task ;
@@ -228,10 +259,11 @@ public Task<T> CreateCancelTask<T>(long delayMillis = 0L)
228259 /// </summary>
229260 /// <param name="action">The action to invoke before completing the task.</param>
230261 /// <param name="delayMillis">The time to delay this task.</param>
262+ /// <param name="absolute">Should the <paramref name="delayMillis"/> be interpreted as absolute time?</param>
231263 /// <returns>The task to await</returns>
232- public Task CreateActionTask ( Action action , long delayMillis = 0L )
264+ public Task CreateActionTask ( Action action , long delayMillis = 0L , bool absolute = false )
233265 {
234- var now = Volatile . Read ( ref _now ) + delayMillis ;
266+ var now = ( absolute ? 0L : Volatile . Read ( ref _now ) ) + delayMillis ;
235267 var tcs = new TaskCompletionSource < bool > ( ) ;
236268 Enqueue ( new ActionTaskTask ( now , tcs , action ) ) ;
237269 return tcs . Task ;
@@ -245,10 +277,11 @@ public Task CreateActionTask(Action action, long delayMillis = 0L)
245277 /// </summary>
246278 /// <param name="action">The action to invoke.</param>
247279 /// <param name="delayMillis">The time to delay this task.</param>
280+ /// <param name="absolute">Should the <paramref name="delayMillis"/> be interpreted as absolute time?</param>
248281 /// <returns>The task to await</returns>
249- public Task < T > CreateLambdaTask < T > ( Action < TaskCompletionSource < T > > action , long delayMillis = 0L )
282+ public Task < T > CreateLambdaTask < T > ( Action < TaskCompletionSource < T > > action , long delayMillis = 0L , bool absolute = false )
250283 {
251- var now = Volatile . Read ( ref _now ) + delayMillis ;
284+ var now = ( absolute ? 0L : Volatile . Read ( ref _now ) ) + delayMillis ;
252285 var tcs = new TaskCompletionSource < T > ( ) ;
253286 Enqueue ( new LambdaTaskTask < T > ( now , tcs , action ) ) ;
254287 return tcs . Task ;
0 commit comments