@@ -382,49 +382,64 @@ protected virtual void RaiseOnStart()
382
382
OnStart ? . Invoke ( this ) ;
383
383
}
384
384
385
+ protected virtual bool RaiseFaultHandlers ( Exception ex )
386
+ {
387
+ taskFailed = true ;
388
+ exception = ex ;
389
+ if ( catchHandler == null )
390
+ return false ;
391
+ foreach ( var handler in catchHandler . GetInvocationList ( ) )
392
+ {
393
+ if ( ( bool ) handler . DynamicInvoke ( new object [ ] { ex } ) )
394
+ {
395
+ exceptionWasHandled = true ;
396
+ break ;
397
+ }
398
+ }
399
+ // if a catch handler returned true, don't throw
400
+ return exceptionWasHandled ;
401
+ }
402
+
385
403
protected virtual void RaiseOnEnd ( )
386
404
{
387
405
OnEnd ? . Invoke ( this , ! taskFailed , exception ) ;
406
+ SetupContinuations ( ) ;
407
+ //Logger.Trace($"Finished {ToString()}");
408
+ }
409
+
410
+ protected void SetupContinuations ( )
411
+ {
388
412
if ( ! taskFailed || exceptionWasHandled )
389
413
{
390
- if ( continuationOnSuccess == null )
391
- CallFinallyHandler ( ) ;
414
+ var taskToContinueWith = continuationOnSuccess ?? continuationOnAlways ;
415
+ if ( taskToContinueWith != null )
416
+ SetContinuation ( taskToContinueWith , runOnSuccessOptions ) ;
392
417
else
393
- SetContinuation ( continuationOnSuccess , runOnSuccessOptions ) ;
418
+ { // there are no more tasks to schedule, call a finally handler if it exists
419
+ // we need to do this only when there are no more continuations
420
+ // so that the in-thread finally handler is guaranteed to run after any Finally tasks
421
+ CallFinallyHandler ( ) ;
422
+ }
394
423
}
395
424
else
396
425
{
397
- if ( continuationOnFailure == null )
398
- CallFinallyHandler ( ) ;
426
+ var taskToContinueWith = continuationOnFailure ?? continuationOnAlways ;
427
+ if ( taskToContinueWith != null )
428
+ SetContinuation ( taskToContinueWith , runOnFaultOptions ) ;
399
429
else
400
- SetContinuation ( continuationOnFailure , runOnSuccessOptions ) ;
430
+ { // there are no more tasks to schedule, call a finally handler if it exists
431
+ // we need to do this only when there are no more continuations
432
+ // so that the in-thread finally handler is guaranteed to run after any Finally tasks
433
+ CallFinallyHandler ( ) ;
434
+ }
401
435
}
402
- //Logger.Trace($"Finished {ToString()}");
403
436
}
404
437
405
- protected void CallFinallyHandler ( )
438
+ protected virtual void CallFinallyHandler ( )
406
439
{
407
440
finallyHandler ? . Invoke ( ! taskFailed ) ;
408
441
}
409
442
410
- protected virtual bool RaiseFaultHandlers ( Exception ex )
411
- {
412
- taskFailed = true ;
413
- exception = ex ;
414
- if ( catchHandler == null )
415
- return continuationOnFailure != null ;
416
- foreach ( var handler in catchHandler . GetInvocationList ( ) )
417
- {
418
- if ( ( bool ) handler . DynamicInvoke ( new object [ ] { ex } ) )
419
- {
420
- exceptionWasHandled = true ;
421
- break ;
422
- }
423
- }
424
- // if a catch handler returned true or we have a continuation for failure cases, don't throw
425
- return exceptionWasHandled || continuationOnFailure != null ;
426
- }
427
-
428
443
protected Exception GetThrownException ( )
429
444
{
430
445
if ( DependsOn == null )
@@ -617,16 +632,15 @@ protected virtual void RaiseOnEnd(TResult data)
617
632
{
618
633
this . result = data ;
619
634
OnEnd ? . Invoke ( this , result , ! taskFailed , exception ) ;
620
- if ( continuationOnSuccess == null && continuationOnFailure == null )
621
- {
622
- finallyHandler ? . Invoke ( ! taskFailed , result ) ;
623
- CallFinallyHandler ( ) ;
624
- }
625
- else if ( continuationOnSuccess != null )
626
- SetContinuation ( continuationOnSuccess , runOnSuccessOptions ) ;
635
+ SetupContinuations ( ) ;
627
636
//Logger.Trace($"Finished {ToString()} {result}");
628
637
}
629
638
639
+ protected override void CallFinallyHandler ( )
640
+ {
641
+ finallyHandler ? . Invoke ( ! taskFailed , result ) ;
642
+ }
643
+
630
644
public new Task < TResult > Task
631
645
{
632
646
get { return base . Task as Task < TResult > ; }
0 commit comments