Skip to content

Commit db4dd1c

Browse files
author
Meyn
committed
Increase Readability of Request
1 parent 762f083 commit db4dd1c

File tree

1 file changed

+68
-63
lines changed

1 file changed

+68
-63
lines changed

Requests/Request.cs

Lines changed: 68 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Requests.Options;
22
using System.Diagnostics;
3+
using System.Diagnostics.CodeAnalysis;
34

45
namespace 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

Comments
 (0)