11using Requests . Options ;
22using System . Diagnostics ;
3+ using System . Diagnostics . CodeAnalysis ;
34
45namespace Requests
56{
@@ -25,7 +26,7 @@ namespace Requests
2526 /// <summary>
2627 /// The <see cref="CancellationTokenSource"/> for this object.
2728 /// </summary>
28- private CancellationTokenSource _cts = null ! ;
29+ private CancellationTokenSource _cts ;
2930
3031 /// <summary>
3132 /// The <see cref="CancellationTokenRegistration"/> for this object.
@@ -80,7 +81,7 @@ namespace Requests
8081 /// <summary>
8182 /// <see cref="AggregateException"/> that contains the throwed Exeptions
8283 /// </summary>
83- public virtual AggregateException ? Exception => _exceptions . Count == 0 ? null : new AggregateException ( _exceptions ) ;
84+ public virtual AggregateException ? Exception { private set ; get ; }
8485
8586 /// <summary>
8687 /// Delays the start of the <see cref="Request{TOptions, TCompleated, TFailed}"/> on every Start call for the specified number of milliseconds.
@@ -123,23 +124,32 @@ protected Request(TOptions? options = null)
123124 _startOptions = options ?? new ( ) ;
124125 Options = _startOptions with { } ;
125126 SynchronizationContext = SynchronizationContext . Current ?? Options . Handler . DefaultSynchronizationContext ;
126- NewCTS ( ) ;
127+ RegisterNewCTS ( ) ;
127128 }
128129
129130 /// <summary>
130131 /// Releases all Recouces of <see cref="_ctr"/> and <see cref="_cts"/> and sets them new
131132 /// </summary>
132- private void NewCTS ( )
133+ [ MemberNotNull ( nameof ( _cts ) ) ]
134+ private void RegisterNewCTS ( )
133135 {
134136 _cts ? . Dispose ( ) ;
135137 _ctr . Unregister ( ) ;
136- if ( Options . CancellationToken . HasValue )
137- _cts = CancellationTokenSource . CreateLinkedTokenSource ( Options . Handler . CT , Options . CancellationToken . Value ) ;
138- else
139- _cts = CancellationTokenSource . CreateLinkedTokenSource ( Options . Handler . CT ) ;
138+ _cts = CreateNewCTS ( ) ;
140139 _ctr = Token . Register ( ( ) => SynchronizationContext . Post ( ( o ) => Options . RequestCancelled ? . Invoke ( ( IRequest ) o ! ) , this ) ) ;
141140 }
142141
142+ /// <summary>
143+ /// Creates an new Linked Cancelation Token Source
144+ /// </summary>
145+ /// <returns></returns>
146+ private CancellationTokenSource CreateNewCTS ( )
147+ {
148+ if ( Options . CancellationToken . HasValue )
149+ return CancellationTokenSource . CreateLinkedTokenSource ( Options . Handler . CT , Options . CancellationToken . Value ) ;
150+ return CancellationTokenSource . CreateLinkedTokenSource ( Options . Handler . CT ) ;
151+ }
152+
143153 /// <summary>
144154 /// Cancel the <see cref="Request{TOptions, TCompleated, TFailed}"/>
145155 /// </summary>
@@ -198,20 +208,22 @@ protected void AutoStart()
198208 /// </summary>
199209 async Task IRequest . StartRequestAsync ( )
200210 {
201- if ( State != RequestState . Idle || ( Options . CancellationToken . HasValue && Options . CancellationToken . Value . IsCancellationRequested ) )
211+ if ( State != RequestState . Idle || Options . Handler . CT . IsCancellationRequested || Options . CancellationToken ? . IsCancellationRequested == true )
202212 return ;
203213 State = RequestState . Running ;
204214
205215 if ( _cts . IsCancellationRequested )
206- {
207- if ( Options . Handler . CT . IsCancellationRequested )
208- return ;
209- NewCTS ( ) ;
210- }
211-
212- RequestReturn returnItem = new ( ) ;
216+ RegisterNewCTS ( ) ;
213217
214218 SynchronizationContext . Post ( ( o ) => Options . RequestStarted ? . Invoke ( ( IRequest ) o ! ) , this ) ;
219+
220+ RequestReturn returnItem = await TryRunRequestAsync ( ) ;
221+ SetResult ( returnItem ) ;
222+ }
223+
224+ private async Task < Request < TOptions , TCompleated , TFailed > . RequestReturn > TryRunRequestAsync ( )
225+ {
226+ RequestReturn returnItem = new ( ) ;
215227 try
216228 {
217229 returnItem = await RunRequestAsync ( ) ;
@@ -221,8 +233,7 @@ async Task IRequest.StartRequestAsync()
221233 AddException ( ex ) ;
222234 Debug . Assert ( false , ex . Message ) ;
223235 }
224-
225- SetResult ( returnItem ) ;
236+ return returnItem ;
226237 }
227238
228239 /// <summary>
@@ -231,34 +242,35 @@ async Task IRequest.StartRequestAsync()
231242 /// <param name="returnItem"></param>
232243 private void SetResult ( RequestReturn returnItem )
233244 {
234- if ( State == RequestState . Running )
235- if ( returnItem . Successful )
245+ EvalueateRequest ( returnItem ) ;
246+ SetTaskState ( ) ;
247+ }
248+
249+ private void EvalueateRequest ( Request < TOptions , TCompleated , TFailed > . RequestReturn returnItem )
250+ {
251+ if ( State != RequestState . Running )
252+ return ;
253+ if ( ! returnItem . Successful )
254+ {
255+ if ( Token . IsCancellationRequested || AttemptCounter ++ < Options . NumberOfAttempts )
236256 {
237- State = RequestState . Compleated ;
238- SynchronizationContext . Post ( ( o ) => Options . RequestCompleated ? . Invoke ( ( IRequest ) o ! , returnItem . CompleatedReturn ) , this ) ;
239- }
240- else if ( Token . IsCancellationRequested )
241- if ( Options . CancellationToken . HasValue && Options . CancellationToken . Value . IsCancellationRequested )
257+ if ( Options . CancellationToken ? . IsCancellationRequested == true )
242258 State = RequestState . Cancelled ;
259+ else if ( Options . DelayBetweenAttemps . HasValue )
260+ _ = WaitAndDeploy ( Options . DelayBetweenAttemps . Value ) ;
243261 else
244262 State = RequestState . Idle ;
245- else if ( AttemptCounter ++ < Options . NumberOfAttempts )
246- if ( Options . DelayBetweenAttemps . HasValue )
247- {
248- State = RequestState . Waiting ;
249- Task . Run ( ( ) => WaitAndDeploy ( Options . DelayBetweenAttemps . Value ) ) ;
250- }
251- else
252- State = RequestState . Idle ;
253- else
254- {
255- State = RequestState . Failed ;
256- SynchronizationContext . Post ( ( o ) => Options . RequestFailed ? . Invoke ( ( IRequest ) o ! , returnItem . FailedReturn ) , this ) ;
263+ return ;
257264 }
258-
259- SetTaskState ( ) ;
265+ State = RequestState . Failed ;
266+ SynchronizationContext . Post ( ( o ) => Options . RequestFailed ? . Invoke ( ( IRequest ) o ! , returnItem . FailedReturn ) , this ) ;
267+ return ;
268+ }
269+ State = RequestState . Compleated ;
270+ SynchronizationContext . Post ( ( o ) => Options . RequestCompleated ? . Invoke ( ( IRequest ) o ! , returnItem . CompleatedReturn ) , this ) ;
260271 }
261272
273+
262274 /// <summary>
263275 /// Sets the Status of the Task
264276 /// </summary>
@@ -269,19 +281,24 @@ private void SetTaskState()
269281 case RequestState . Compleated :
270282 _isFinished . TrySetResult ( ) ;
271283 break ;
272- case RequestState . Cancelled :
273- _isFinished . TrySetCanceled ( ) ;
274- break ;
275284 case RequestState . Failed :
276285 _isFinished . TrySetResult ( ) ;
277286 break ;
287+ case RequestState . Cancelled :
288+ _isFinished . TrySetCanceled ( ) ;
289+ break ;
290+
278291 }
279292 }
280293
281294 /// <summary>
282295 /// Adds a <see cref="Exception"/> to the <see cref="Exception"/> trace
283296 /// </summary>
284- protected void AddException ( Exception exception ) => _exceptions . Add ( exception ) ;
297+ protected void AddException ( Exception exception )
298+ {
299+ _exceptions . Add ( exception ) ;
300+ Exception = new AggregateException ( _exceptions ) ;
301+ }
285302
286303 /// <summary>
287304 /// Handles the <see cref="Request{TOptions, TCompleated, TFailed}"/> that the <see cref="HttpClient"/> should start.
@@ -296,11 +313,13 @@ public virtual void Start()
296313 {
297314 if ( State != RequestState . Paused )
298315 return ;
299- State = DeployDelay . HasValue ? RequestState . Waiting : RequestState . Idle ;
300316 if ( DeployDelay . HasValue )
301- Task . Run ( ( ) => WaitAndDeploy ( DeployDelay . Value ) ) ;
302- else
303- Options . Handler . RunRequests ( this ) ;
317+ {
318+ _ = WaitAndDeploy ( DeployDelay . Value ) ;
319+ return ;
320+ }
321+ State = RequestState . Idle ;
322+ Options . Handler . RunRequests ( this ) ;
304323 }
305324
306325 /// <summary>
@@ -309,8 +328,7 @@ public virtual void Start()
309328 /// <param name="timeSpan">Time span to the deploy</param>
310329 private async Task WaitAndDeploy ( TimeSpan timeSpan )
311330 {
312- if ( State != RequestState . Waiting )
313- return ;
331+ State = RequestState . Waiting ;
314332 await Task . Delay ( timeSpan ) ;
315333 if ( State != RequestState . Waiting )
316334 return ;
@@ -328,19 +346,6 @@ private async Task WaitAndDeploy(TimeSpan timeSpan)
328346 /// </summary>
329347 protected class RequestReturn
330348 {
331- /// <summary>
332- /// Contructor to set the return types
333- /// </summary>
334- /// <param name="successful">Bool that indicates success</param>
335- /// <param name="compleatedReturn">Object that will be returned if completed</param>
336- /// <param name="failedReturn">Object rthat will be retuned if failed</param>
337- public RequestReturn ( bool successful , TCompleated compleatedReturn , TFailed failedReturn )
338- {
339- Successful = successful ;
340- CompleatedReturn = compleatedReturn ;
341- FailedReturn = failedReturn ;
342- }
343-
344349 /// <summary>
345350 /// Main constructor
346351 /// </summary>
@@ -359,7 +364,7 @@ public RequestReturn() { }
359364 /// <summary>
360365 /// Indicates if the <see cref="Request{TOptions, TCompleated, TFailed}"/> was successful.
361366 /// </summary>
362- public bool Successful { get ; set ; } = false ;
367+ public bool Successful { get ; set ; }
363368 }
364369 }
365370}
0 commit comments