Repository: App-vNext/Polly

Issue:
Finalize the V8 API
We should finalize the V8 API:

- Based on the alpha release feedback.
- Address or close any comments in #1233





Hints:

Patch:
diff --git a/bench/Polly.Core.Benchmarks/CreationBenchmark.cs b/bench/Polly.Core.Benchmarks/CreationBenchmark.cs
index ac3e507b2bf..52c44f037e2 100644
--- a/bench/Polly.Core.Benchmarks/CreationBenchmark.cs
+++ b/bench/Polly.Core.Benchmarks/CreationBenchmark.cs
@@ -18,7 +18,7 @@ public static void Fallback_V8()
         new ResiliencePipelineBuilder<string>()
             .AddFallback(new()
             {
-                FallbackAction = _ => Outcome.FromResultAsTask("fallback")
+                FallbackAction = _ => Outcome.FromResultAsValueTask("fallback")
             })
             .Build();
     }
diff --git a/bench/Polly.Core.Benchmarks/PredicateBenchmark.cs b/bench/Polly.Core.Benchmarks/PredicateBenchmark.cs
index 77948b2ab05..7fa8cf0ccd5 100644
--- a/bench/Polly.Core.Benchmarks/PredicateBenchmark.cs
+++ b/bench/Polly.Core.Benchmarks/PredicateBenchmark.cs
@@ -14,11 +14,11 @@ public class PredicateBenchmark
     {
         ShouldHandle = args => args.Outcome switch
         {
-            { Result: { StatusCode: HttpStatusCode.InternalServerError } } => PredicateResult.True,
-            { Exception: HttpRequestException } => PredicateResult.True,
-            { Exception: IOException } => PredicateResult.True,
-            { Exception: InvalidOperationException } => PredicateResult.False,
-            _ => PredicateResult.False,
+            { Result: { StatusCode: HttpStatusCode.InternalServerError } } => PredicateResult.True(),
+            { Exception: HttpRequestException } => PredicateResult.True(),
+            { Exception: IOException } => PredicateResult.True(),
+            { Exception: InvalidOperationException } => PredicateResult.False(),
+            _ => PredicateResult.False(),
         }
     };
 
diff --git a/bench/Polly.Core.Benchmarks/ResiliencePipelineBenchmark.cs b/bench/Polly.Core.Benchmarks/ResiliencePipelineBenchmark.cs
index 55bea8960cb..54ef684a26a 100644
--- a/bench/Polly.Core.Benchmarks/ResiliencePipelineBenchmark.cs
+++ b/bench/Polly.Core.Benchmarks/ResiliencePipelineBenchmark.cs
@@ -10,7 +10,7 @@ public class ResiliencePipelineBenchmark
     public async ValueTask ExecuteOutcomeAsync()
     {
         var context = ResilienceContextPool.Shared.Get();
-        await ResiliencePipeline.Empty.ExecuteOutcomeAsync((_, _) => Outcome.FromResultAsTask("dummy"), context, "state").ConfigureAwait(false);
+        await ResiliencePipeline.Empty.ExecuteOutcomeAsync((_, _) => Outcome.FromResultAsValueTask("dummy"), context, "state").ConfigureAwait(false);
         ResilienceContextPool.Shared.Return(context);
     }
 
diff --git a/bench/Polly.Core.Benchmarks/TelemetryBenchmark.cs b/bench/Polly.Core.Benchmarks/TelemetryBenchmark.cs
index e4ca157469f..667e8d30b1a 100644
--- a/bench/Polly.Core.Benchmarks/TelemetryBenchmark.cs
+++ b/bench/Polly.Core.Benchmarks/TelemetryBenchmark.cs
@@ -33,7 +33,7 @@ public void Prepare()
     public async ValueTask Execute()
     {
         var context = ResilienceContextPool.Shared.Get();
-        await _pipeline!.ExecuteOutcomeAsync((_, _) => Outcome.FromResultAsTask("dummy"), context, "state").ConfigureAwait(false);
+        await _pipeline!.ExecuteOutcomeAsync((_, _) => Outcome.FromResultAsValueTask("dummy"), context, "state").ConfigureAwait(false);
         ResilienceContextPool.Shared.Return(context);
     }
 
diff --git a/bench/Polly.Core.Benchmarks/Utils/Helper.CircuitBreaker.cs b/bench/Polly.Core.Benchmarks/Utils/Helper.CircuitBreaker.cs
index c4d2c358d41..c7cd8f451bb 100644
--- a/bench/Polly.Core.Benchmarks/Utils/Helper.CircuitBreaker.cs
+++ b/bench/Polly.Core.Benchmarks/Utils/Helper.CircuitBreaker.cs
@@ -7,7 +7,7 @@ public static object CreateOpenedCircuitBreaker(PollyVersion version, bool handl
         var manualControl = new CircuitBreakerManualControl();
         var options = new CircuitBreakerStrategyOptions
         {
-            ShouldHandle = _ => PredicateResult.True,
+            ShouldHandle = _ => PredicateResult.True(),
             ManualControl = manualControl,
         };
 
@@ -54,9 +54,9 @@ public static object CreateCircuitBreaker(PollyVersion technology)
                     BreakDuration = TimeSpan.FromSeconds(5),
                     ShouldHandle = args => args.Outcome switch
                     {
-                        { Exception: InvalidOperationException } => PredicateResult.True,
-                        { Result: string result } when result == Failure => PredicateResult.True,
-                        _ => PredicateResult.False
+                        { Exception: InvalidOperationException } => PredicateResult.True(),
+                        { Result: string result } when result == Failure => PredicateResult.True(),
+                        _ => PredicateResult.False()
                     }
                 });
             }),
diff --git a/bench/Polly.Core.Benchmarks/Utils/Helper.Hedging.cs b/bench/Polly.Core.Benchmarks/Utils/Helper.Hedging.cs
index 7b5b62aa7c7..856e5a8a7af 100644
--- a/bench/Polly.Core.Benchmarks/Utils/Helper.Hedging.cs
+++ b/bench/Polly.Core.Benchmarks/Utils/Helper.Hedging.cs
@@ -13,7 +13,7 @@ public static ResiliencePipeline<string> CreateHedging()
             builder.AddHedging(new HedgingStrategyOptions<string>
             {
                 ShouldHandle = args => new ValueTask<bool>(args.Outcome.Result == Failure),
-                ActionGenerator = args => () => Outcome.FromResultAsTask("hedged response"),
+                ActionGenerator = args => () => Outcome.FromResultAsValueTask("hedged response"),
             });
         });
     }
diff --git a/bench/Polly.Core.Benchmarks/Utils/Helper.MultipleStrategies.cs b/bench/Polly.Core.Benchmarks/Utils/Helper.MultipleStrategies.cs
index 5b15fa917c1..1ff82eaaf8e 100644
--- a/bench/Polly.Core.Benchmarks/Utils/Helper.MultipleStrategies.cs
+++ b/bench/Polly.Core.Benchmarks/Utils/Helper.MultipleStrategies.cs
@@ -29,9 +29,9 @@ internal static partial class Helper
                     Delay = TimeSpan.FromSeconds(1),
                     ShouldHandle = args => args.Outcome switch
                     {
-                        { Exception: InvalidOperationException } => PredicateResult.True,
-                        { Result: string result } when result == Failure => PredicateResult.True,
-                        _ => PredicateResult.False
+                        { Exception: InvalidOperationException } => PredicateResult.True(),
+                        { Result: string result } when result == Failure => PredicateResult.True(),
+                        _ => PredicateResult.False()
                     }
                 })
                 .AddTimeout(TimeSpan.FromSeconds(1))
@@ -43,9 +43,9 @@ internal static partial class Helper
                     BreakDuration = TimeSpan.FromSeconds(5),
                     ShouldHandle = args => args.Outcome switch
                     {
-                        { Exception: InvalidOperationException } => PredicateResult.True,
-                        { Result: string result } when result == Failure => PredicateResult.True,
-                        _ => PredicateResult.False
+                        { Exception: InvalidOperationException } => PredicateResult.True(),
+                        { Result: string result } when result == Failure => PredicateResult.True(),
+                        _ => PredicateResult.False()
                     }
                 });
 
@@ -73,9 +73,9 @@ public static ResiliencePipeline CreateNonGenericStrategyPipeline(bool telemetry
                 Delay = TimeSpan.FromSeconds(1),
                 ShouldHandle = args => args.Outcome switch
                 {
-                    { Exception: InvalidOperationException } => PredicateResult.True,
-                    { Result: string result } when result == Failure => PredicateResult.True,
-                    _ => PredicateResult.False
+                    { Exception: InvalidOperationException } => PredicateResult.True(),
+                    { Result: string result } when result == Failure => PredicateResult.True(),
+                    _ => PredicateResult.False()
                 }
             })
             .AddTimeout(TimeSpan.FromSeconds(1))
@@ -87,9 +87,9 @@ public static ResiliencePipeline CreateNonGenericStrategyPipeline(bool telemetry
                 BreakDuration = TimeSpan.FromSeconds(5),
                 ShouldHandle = args => args.Outcome switch
                 {
-                    { Exception: InvalidOperationException } => PredicateResult.True,
-                    { Result: string result } when result == Failure => PredicateResult.True,
-                    _ => PredicateResult.False
+                    { Exception: InvalidOperationException } => PredicateResult.True(),
+                    { Result: string result } when result == Failure => PredicateResult.True(),
+                    _ => PredicateResult.False()
                 }
             });
 
diff --git a/bench/Polly.Core.Benchmarks/Utils/Helper.Retry.cs b/bench/Polly.Core.Benchmarks/Utils/Helper.Retry.cs
index 4d49ef66825..ae3297d0a31 100644
--- a/bench/Polly.Core.Benchmarks/Utils/Helper.Retry.cs
+++ b/bench/Polly.Core.Benchmarks/Utils/Helper.Retry.cs
@@ -23,9 +23,9 @@ public static object CreateRetry(PollyVersion technology)
                     Delay = delay,
                     ShouldHandle = args => args.Outcome switch
                     {
-                        { Exception: InvalidOperationException } => PredicateResult.True,
-                        { Result: string result } when result == Failure => PredicateResult.True,
-                        _ => PredicateResult.False
+                        { Exception: InvalidOperationException } => PredicateResult.True(),
+                        { Result: string result } when result == Failure => PredicateResult.True(),
+                        _ => PredicateResult.False()
                     },
                     OnRetry = _ => default
                 });
diff --git a/bench/Polly.Core.Benchmarks/Utils/Helper.cs b/bench/Polly.Core.Benchmarks/Utils/Helper.cs
index f0acdc8f243..9fefb506a69 100644
--- a/bench/Polly.Core.Benchmarks/Utils/Helper.cs
+++ b/bench/Polly.Core.Benchmarks/Utils/Helper.cs
@@ -15,7 +15,7 @@ public static async ValueTask ExecuteAsync(this object obj, PollyVersion version
                 var context = ResilienceContextPool.Shared.Get();
 
                 await ((ResiliencePipeline<string>)obj).ExecuteOutcomeAsync(
-                    static (_, _) => Outcome.FromResultAsTask("dummy"),
+                    static (_, _) => Outcome.FromResultAsValueTask("dummy"),
                     context,
                     string.Empty).ConfigureAwait(false);
 
diff --git a/src/Polly.Core/CircuitBreaker/Controller/CircuitStateController.cs b/src/Polly.Core/CircuitBreaker/Controller/CircuitStateController.cs
index cc56c1b87aa..fcd35117e06 100644
--- a/src/Polly.Core/CircuitBreaker/Controller/CircuitStateController.cs
+++ b/src/Polly.Core/CircuitBreaker/Controller/CircuitStateController.cs
@@ -298,9 +298,9 @@ private void SetLastHandledOutcome_NeedsLock(Outcome<T> outcome)
         {
             _breakingException = new BrokenCircuitException(BrokenCircuitException.DefaultMessage, exception);
         }
-        else if (outcome.TryGetResult(out var result))
+        else
         {
-            _breakingException = new BrokenCircuitException<T>(BrokenCircuitException.DefaultMessage, result!);
+            _breakingException = new BrokenCircuitException(BrokenCircuitException.DefaultMessage);
         }
     }
 
diff --git a/src/Polly.Core/Outcome.TResult.cs b/src/Polly.Core/Outcome.TResult.cs
index 2bb88010b36..ad5a077fce9 100644
--- a/src/Polly.Core/Outcome.TResult.cs
+++ b/src/Polly.Core/Outcome.TResult.cs
@@ -56,7 +56,7 @@ internal Outcome(ExceptionDispatchInfo exceptionDispatchInfo)
     /// <remarks>
     /// If the operation produced a result, this method does nothing. The thrown exception maintains its original stack trace.
     /// </remarks>
-    public void EnsureSuccess() => ExceptionDispatchInfo?.Throw();
+    public void ThrowIfException() => ExceptionDispatchInfo?.Throw();
 
     /// <summary>
     /// Tries to get the result, if available.
diff --git a/src/Polly.Core/Outcome.cs b/src/Polly.Core/Outcome.cs
index adf0a210fe5..ec6b79e2950 100644
--- a/src/Polly.Core/Outcome.cs
+++ b/src/Polly.Core/Outcome.cs
@@ -19,7 +19,7 @@ public static class Outcome
     /// <typeparam name="TResult">The type of the result.</typeparam>
     /// <param name="value">The result value.</param>
     /// <returns>A completed <see cref="ValueTask{TResult}"/> that produces <see cref="Outcome{TResult}"/>.</returns>
-    public static ValueTask<Outcome<TResult>> FromResultAsTask<TResult>(TResult value) => new(FromResult(value));
+    public static ValueTask<Outcome<TResult>> FromResultAsValueTask<TResult>(TResult value) => new(FromResult(value));
 
     /// <summary>
     /// Returns a <see cref="Outcome{TResult}"/> with the given <paramref name="exception"/>.
@@ -42,7 +42,7 @@ public static Outcome<TResult> FromException<TResult>(Exception exception)
     /// <param name="exception">The exception.</param>
     /// <returns>A completed <see cref="ValueTask{TResult}"/> that produces <see cref="Outcome{TResult}"/>.</returns>
     /// <exception cref="ArgumentNullException">Thrown when <paramref name="exception"/> is <see langword="null"/>.</exception>
-    public static ValueTask<Outcome<TResult>> FromExceptionAsTask<TResult>(Exception exception)
+    public static ValueTask<Outcome<TResult>> FromExceptionAsValueTask<TResult>(Exception exception)
     {
         Guard.NotNull(exception);
 
diff --git a/src/Polly.Core/PredicateResult.cs b/src/Polly.Core/PredicateResult.cs
index 89daced9217..49356ac67cb 100644
--- a/src/Polly.Core/PredicateResult.cs
+++ b/src/Polly.Core/PredicateResult.cs
@@ -6,12 +6,14 @@ namespace Polly;
 public static class PredicateResult
 {
     /// <summary>
-    /// Gets a finished <see cref="ValueTask{TResult}"/> that returns <see langword="true"/> value.
+    /// Returns a finished <see cref="ValueTask{TResult}"/> that returns <see langword="true"/> value.
     /// </summary>
-    public static ValueTask<bool> True => new(true);
+    /// <returns>A new instance of finished <see cref="ValueTask{TResult}"/>.</returns>
+    public static ValueTask<bool> True() => new(true);
 
     /// <summary>
-    /// Gets a finished <see cref="ValueTask{TResult}"/> that returns <see langword="false"/> value.
+    /// Returns a finished <see cref="ValueTask{TResult}"/> that returns <see langword="false"/> value.
     /// </summary>
-    public static ValueTask<bool> False => new(false);
+    /// <returns>A new instance of finished <see cref="ValueTask{TResult}"/>.</returns>
+    public static ValueTask<bool> False() => new(false);
 }
diff --git a/src/Polly.Core/PublicAPI.Unshipped.txt b/src/Polly.Core/PublicAPI.Unshipped.txt
index d690461ed16..74c19f8c4ed 100644
--- a/src/Polly.Core/PublicAPI.Unshipped.txt
+++ b/src/Polly.Core/PublicAPI.Unshipped.txt
@@ -15,11 +15,6 @@ Polly.CircuitBreaker.BrokenCircuitException
 Polly.CircuitBreaker.BrokenCircuitException.BrokenCircuitException() -> void
 Polly.CircuitBreaker.BrokenCircuitException.BrokenCircuitException(string! message) -> void
 Polly.CircuitBreaker.BrokenCircuitException.BrokenCircuitException(string! message, System.Exception! inner) -> void
-Polly.CircuitBreaker.BrokenCircuitException<TResult>
-Polly.CircuitBreaker.BrokenCircuitException<TResult>.BrokenCircuitException(string! message, System.Exception! inner, TResult result) -> void
-Polly.CircuitBreaker.BrokenCircuitException<TResult>.BrokenCircuitException(string! message, TResult result) -> void
-Polly.CircuitBreaker.BrokenCircuitException<TResult>.BrokenCircuitException(TResult result) -> void
-Polly.CircuitBreaker.BrokenCircuitException<TResult>.Result.get -> TResult
 Polly.CircuitBreaker.CircuitBreakerManualControl
 Polly.CircuitBreaker.CircuitBreakerManualControl.CircuitBreakerManualControl() -> void
 Polly.CircuitBreaker.CircuitBreakerManualControl.CircuitBreakerManualControl(bool isIsolated) -> void
@@ -158,10 +153,10 @@ Polly.HedgingResiliencePipelineBuilderExtensions
 Polly.LegacySupport
 Polly.Outcome
 Polly.Outcome<TResult>
-Polly.Outcome<TResult>.EnsureSuccess() -> void
 Polly.Outcome<TResult>.Exception.get -> System.Exception?
 Polly.Outcome<TResult>.Outcome() -> void
 Polly.Outcome<TResult>.Result.get -> TResult?
+Polly.Outcome<TResult>.ThrowIfException() -> void
 Polly.PredicateBuilder
 Polly.PredicateBuilder.PredicateBuilder() -> void
 Polly.PredicateBuilder<TResult>
@@ -296,10 +291,9 @@ Polly.Retry.OnRetryArguments<TResult>.RetryDelay.get -> System.TimeSpan
 Polly.Retry.RetryDelayGeneratorArguments<TResult>
 Polly.Retry.RetryDelayGeneratorArguments<TResult>.AttemptNumber.get -> int
 Polly.Retry.RetryDelayGeneratorArguments<TResult>.Context.get -> Polly.ResilienceContext!
-Polly.Retry.RetryDelayGeneratorArguments<TResult>.DelayHint.get -> System.TimeSpan
 Polly.Retry.RetryDelayGeneratorArguments<TResult>.Outcome.get -> Polly.Outcome<TResult>
 Polly.Retry.RetryDelayGeneratorArguments<TResult>.RetryDelayGeneratorArguments() -> void
-Polly.Retry.RetryDelayGeneratorArguments<TResult>.RetryDelayGeneratorArguments(Polly.ResilienceContext! context, Polly.Outcome<TResult> outcome, int attemptNumber, System.TimeSpan delayHint) -> void
+Polly.Retry.RetryDelayGeneratorArguments<TResult>.RetryDelayGeneratorArguments(Polly.ResilienceContext! context, Polly.Outcome<TResult> outcome, int attemptNumber) -> void
 Polly.Retry.RetryPredicateArguments<TResult>
 Polly.Retry.RetryPredicateArguments<TResult>.AttemptNumber.get -> int
 Polly.Retry.RetryPredicateArguments<TResult>.Context.get -> Polly.ResilienceContext!
@@ -313,7 +307,7 @@ Polly.Retry.RetryStrategyOptions<TResult>.BackoffType.get -> Polly.DelayBackoffT
 Polly.Retry.RetryStrategyOptions<TResult>.BackoffType.set -> void
 Polly.Retry.RetryStrategyOptions<TResult>.Delay.get -> System.TimeSpan
 Polly.Retry.RetryStrategyOptions<TResult>.Delay.set -> void
-Polly.Retry.RetryStrategyOptions<TResult>.DelayGenerator.get -> System.Func<Polly.Retry.RetryDelayGeneratorArguments<TResult>, System.Threading.Tasks.ValueTask<System.TimeSpan>>?
+Polly.Retry.RetryStrategyOptions<TResult>.DelayGenerator.get -> System.Func<Polly.Retry.RetryDelayGeneratorArguments<TResult>, System.Threading.Tasks.ValueTask<System.TimeSpan?>>?
 Polly.Retry.RetryStrategyOptions<TResult>.DelayGenerator.set -> void
 Polly.Retry.RetryStrategyOptions<TResult>.MaxRetryAttempts.get -> int
 Polly.Retry.RetryStrategyOptions<TResult>.MaxRetryAttempts.set -> void
@@ -403,15 +397,15 @@ static Polly.FallbackResiliencePipelineBuilderExtensions.AddFallback<TResult>(th
 static Polly.HedgingResiliencePipelineBuilderExtensions.AddHedging<TResult>(this Polly.ResiliencePipelineBuilder<TResult>! builder, Polly.Hedging.HedgingStrategyOptions<TResult>! options) -> Polly.ResiliencePipelineBuilder<TResult>!
 static Polly.LegacySupport.SetProperties(this Polly.ResilienceProperties! resilienceProperties, System.Collections.Generic.IDictionary<string!, object?>! properties, out System.Collections.Generic.IDictionary<string!, object?>! oldProperties) -> void
 static Polly.Outcome.FromException<TResult>(System.Exception! exception) -> Polly.Outcome<TResult>
-static Polly.Outcome.FromExceptionAsTask<TResult>(System.Exception! exception) -> System.Threading.Tasks.ValueTask<Polly.Outcome<TResult>>
+static Polly.Outcome.FromExceptionAsValueTask<TResult>(System.Exception! exception) -> System.Threading.Tasks.ValueTask<Polly.Outcome<TResult>>
 static Polly.Outcome.FromResult<TResult>(TResult? value) -> Polly.Outcome<TResult>
-static Polly.Outcome.FromResultAsTask<TResult>(TResult value) -> System.Threading.Tasks.ValueTask<Polly.Outcome<TResult>>
+static Polly.Outcome.FromResultAsValueTask<TResult>(TResult value) -> System.Threading.Tasks.ValueTask<Polly.Outcome<TResult>>
 static Polly.PredicateBuilder<TResult>.implicit operator System.Func<Polly.CircuitBreaker.CircuitBreakerPredicateArguments<TResult>, System.Threading.Tasks.ValueTask<bool>>!(Polly.PredicateBuilder<TResult>! builder) -> System.Func<Polly.CircuitBreaker.CircuitBreakerPredicateArguments<TResult>, System.Threading.Tasks.ValueTask<bool>>!
 static Polly.PredicateBuilder<TResult>.implicit operator System.Func<Polly.Fallback.FallbackPredicateArguments<TResult>, System.Threading.Tasks.ValueTask<bool>>!(Polly.PredicateBuilder<TResult>! builder) -> System.Func<Polly.Fallback.FallbackPredicateArguments<TResult>, System.Threading.Tasks.ValueTask<bool>>!
 static Polly.PredicateBuilder<TResult>.implicit operator System.Func<Polly.Hedging.HedgingPredicateArguments<TResult>, System.Threading.Tasks.ValueTask<bool>>!(Polly.PredicateBuilder<TResult>! builder) -> System.Func<Polly.Hedging.HedgingPredicateArguments<TResult>, System.Threading.Tasks.ValueTask<bool>>!
 static Polly.PredicateBuilder<TResult>.implicit operator System.Func<Polly.Retry.RetryPredicateArguments<TResult>, System.Threading.Tasks.ValueTask<bool>>!(Polly.PredicateBuilder<TResult>! builder) -> System.Func<Polly.Retry.RetryPredicateArguments<TResult>, System.Threading.Tasks.ValueTask<bool>>!
-static Polly.PredicateResult.False.get -> System.Threading.Tasks.ValueTask<bool>
-static Polly.PredicateResult.True.get -> System.Threading.Tasks.ValueTask<bool>
+static Polly.PredicateResult.False() -> System.Threading.Tasks.ValueTask<bool>
+static Polly.PredicateResult.True() -> System.Threading.Tasks.ValueTask<bool>
 static Polly.ResilienceContextPool.Shared.get -> Polly.ResilienceContextPool!
 static Polly.ResiliencePipelineBuilderExtensions.AddPipeline<TBuilder>(this TBuilder! builder, Polly.ResiliencePipeline! pipeline) -> TBuilder!
 static Polly.ResiliencePipelineBuilderExtensions.AddPipeline<TResult>(this Polly.ResiliencePipelineBuilder<TResult>! builder, Polly.ResiliencePipeline<TResult>! pipeline) -> Polly.ResiliencePipelineBuilder<TResult>!
diff --git a/src/Polly.Core/README.md b/src/Polly.Core/README.md
index 867d5e2f828..6140cdc6364 100644
--- a/src/Polly.Core/README.md
+++ b/src/Polly.Core/README.md
@@ -226,10 +226,10 @@ new ResiliencePipelineBuilder()
     {
         ShouldRetry = args => args switch
         {
-            { Exception: InvalidOperationException } => PredicateResult.True,
-            { Result: string result } when result == Failure => PredicateResult.True,
-            { Result: int result } when result == -1 => PredicateResult.True,
-            _ => PredicateResult.False
+            { Exception: InvalidOperationException } => PredicateResult.True(),
+            { Result: string result } when result == Failure => PredicateResult.True(),
+            { Result: int result } when result == -1 => PredicateResult.True(),
+            _ => PredicateResult.False()
         },
     })
     .Build();
@@ -243,9 +243,9 @@ new ResiliencePipelineBuilder()
     {
         ShouldRetry = args => args switch
         {
-            { Exception: InvalidOperationException } => PredicateResult.True,
-            { Result: result } when result == Failure => PredicateResult.True,
-            _ => PredicateResult.False
+            { Exception: InvalidOperationException } => PredicateResult.True(),
+            { Result: result } when result == Failure => PredicateResult.True(),
+            _ => PredicateResult.False()
         },
     })
     .Build();
diff --git a/src/Polly.Core/Retry/RetryDelayGeneratorArguments.cs b/src/Polly.Core/Retry/RetryDelayGeneratorArguments.cs
index 161c99ad6d9..a327ae6e88d 100644
--- a/src/Polly.Core/Retry/RetryDelayGeneratorArguments.cs
+++ b/src/Polly.Core/Retry/RetryDelayGeneratorArguments.cs
@@ -17,13 +17,11 @@ public readonly struct RetryDelayGeneratorArguments<TResult>
     /// <param name="outcome">The context in which the resilience operation or event occurred.</param>
     /// <param name="context">The outcome of the resilience operation or event.</param>
     /// <param name="attemptNumber">The zero-based attempt number.</param>
-    /// <param name="delayHint">The delay suggested by the retry strategy.</param>
-    public RetryDelayGeneratorArguments(ResilienceContext context, Outcome<TResult> outcome, int attemptNumber, TimeSpan delayHint)
+    public RetryDelayGeneratorArguments(ResilienceContext context, Outcome<TResult> outcome, int attemptNumber)
     {
         Context = context;
         Outcome = outcome;
         AttemptNumber = attemptNumber;
-        DelayHint = delayHint;
     }
 
     /// <summary>
@@ -40,9 +38,4 @@ public RetryDelayGeneratorArguments(ResilienceContext context, Outcome<TResult>
     /// Gets The zero-based attempt number.
     /// </summary>
     public int AttemptNumber { get; }
-
-    /// <summary>
-    /// Gets the delay suggested by the retry strategy.
-    /// </summary>
-    public TimeSpan DelayHint { get; }
 }
diff --git a/src/Polly.Core/Retry/RetryResilienceStrategy.cs b/src/Polly.Core/Retry/RetryResilienceStrategy.cs
index 62eccd7e4fa..6d61e7bdaf7 100644
--- a/src/Polly.Core/Retry/RetryResilienceStrategy.cs
+++ b/src/Polly.Core/Retry/RetryResilienceStrategy.cs
@@ -34,7 +34,7 @@ public RetryResilienceStrategy(
 
     public Func<RetryPredicateArguments<T>, ValueTask<bool>> ShouldHandle { get; }
 
-    public Func<RetryDelayGeneratorArguments<T>, ValueTask<TimeSpan>>? DelayGenerator { get; }
+    public Func<RetryDelayGeneratorArguments<T>, ValueTask<TimeSpan?>>? DelayGenerator { get; }
 
     public bool UseJitter { get; }
 
@@ -64,9 +64,9 @@ protected internal override async ValueTask<Outcome<T>> ExecuteCore<TState>(Func
             var delay = RetryHelper.GetRetryDelay(BackoffType, UseJitter, attempt, BaseDelay, ref retryState, _randomizer);
             if (DelayGenerator is not null)
             {
-                var delayArgs = new RetryDelayGeneratorArguments<T>(context, outcome, attempt, delay);
-                var newDelay = await DelayGenerator(delayArgs).ConfigureAwait(false);
-                if (RetryHelper.IsValidDelay(newDelay))
+                var delayArgs = new RetryDelayGeneratorArguments<T>(context, outcome, attempt);
+
+                if (await DelayGenerator(delayArgs).ConfigureAwait(false) is TimeSpan newDelay && RetryHelper.IsValidDelay(newDelay))
                 {
                     delay = newDelay;
                 }
diff --git a/src/Polly.Core/Retry/RetryStrategyOptions.TResult.cs b/src/Polly.Core/Retry/RetryStrategyOptions.TResult.cs
index aa4015af4f7..797d65c981b 100644
--- a/src/Polly.Core/Retry/RetryStrategyOptions.TResult.cs
+++ b/src/Polly.Core/Retry/RetryStrategyOptions.TResult.cs
@@ -85,12 +85,13 @@ public class RetryStrategyOptions<TResult> : ResilienceStrategyOptions
     /// Gets or sets a generator that calculates the delay between retries.
     /// </summary>
     /// <remarks>
-    /// The generator has precedence over <see cref="Delay"/> and <see cref="BackoffType"/>.
+    /// The generator can override the delay generated by the retry strategy. If the generator returns <see langword="null"/>, the delay generated
+    /// by the retry strategy for that attempt will be used.
     /// </remarks>
     /// <value>
     /// The default value is <see langword="null"/>.
     /// </value>
-    public Func<RetryDelayGeneratorArguments<TResult>, ValueTask<TimeSpan>>? DelayGenerator { get; set; }
+    public Func<RetryDelayGeneratorArguments<TResult>, ValueTask<TimeSpan?>>? DelayGenerator { get; set; }
 
     /// <summary>
     /// Gets or sets an event delegate that is raised when the retry happens.
diff --git a/src/Polly.Core/Utils/DefaultPredicates.cs b/src/Polly.Core/Utils/DefaultPredicates.cs
index ae74ed8cbfd..fdbcb3efa55 100644
--- a/src/Polly.Core/Utils/DefaultPredicates.cs
+++ b/src/Polly.Core/Utils/DefaultPredicates.cs
@@ -4,8 +4,8 @@ internal static class DefaultPredicates<TArgs, TResult>
 {
     public static readonly Func<TArgs, ValueTask<bool>> HandleOutcome = args => args.Outcome.Exception switch
     {
-        OperationCanceledException => PredicateResult.False,
-        Exception => PredicateResult.True,
-        _ => PredicateResult.False
+        OperationCanceledException => PredicateResult.False(),
+        Exception => PredicateResult.True(),
+        _ => PredicateResult.False()
     };
 }
diff --git a/src/Polly.Core/Utils/Pipeline/CompositeComponent.cs b/src/Polly.Core/Utils/Pipeline/CompositeComponent.cs
index ef2daa09d1d..8ec9515df29 100644
--- a/src/Polly.Core/Utils/Pipeline/CompositeComponent.cs
+++ b/src/Polly.Core/Utils/Pipeline/CompositeComponent.cs
@@ -97,7 +97,7 @@ private ValueTask<Outcome<TResult>> ExecuteCoreWithoutTelemetry<TResult, TState>
     {
         if (context.CancellationToken.IsCancellationRequested)
         {
-            return Outcome.FromExceptionAsTask<TResult>(new OperationCanceledException(context.CancellationToken).TrySetStackTrace());
+            return Outcome.FromExceptionAsValueTask<TResult>(new OperationCanceledException(context.CancellationToken).TrySetStackTrace());
         }
         else
         {
@@ -146,7 +146,7 @@ internal override ValueTask<Outcome<TResult>> ExecuteCore<TResult, TState>(
                 {
                     if (context.CancellationToken.IsCancellationRequested)
                     {
-                        return Outcome.FromExceptionAsTask<TResult>(new OperationCanceledException(context.CancellationToken).TrySetStackTrace());
+                        return Outcome.FromExceptionAsValueTask<TResult>(new OperationCanceledException(context.CancellationToken).TrySetStackTrace());
                     }
 
                     return state.Next!.ExecuteCore(state.callback, context, state.state);
diff --git a/src/Polly.Core/CircuitBreaker/BrokenCircuitException.TResult.cs b/src/Polly/CircuitBreaker/BrokenCircuitException.TResult.cs
similarity index 100%
rename from src/Polly.Core/CircuitBreaker/BrokenCircuitException.TResult.cs
rename to src/Polly/CircuitBreaker/BrokenCircuitException.TResult.cs
diff --git a/src/Polly/Properties/AssemblyInfo.cs b/src/Polly/Properties/AssemblyInfo.cs
index a96745bc506..b949813529e 100644
--- a/src/Polly/Properties/AssemblyInfo.cs
+++ b/src/Polly/Properties/AssemblyInfo.cs
@@ -6,6 +6,5 @@
 [assembly: TypeForwardedTo(typeof(ExecutionRejectedException))]
 [assembly: TypeForwardedTo(typeof(TimeoutRejectedException))]
 [assembly: TypeForwardedTo(typeof(BrokenCircuitException))]
-[assembly: TypeForwardedTo(typeof(BrokenCircuitException<>))]
 [assembly: TypeForwardedTo(typeof(IsolatedCircuitException))]
 [assembly: TypeForwardedTo(typeof(CircuitState))]
diff --git a/src/Polly/PublicAPI.Shipped.txt b/src/Polly/PublicAPI.Shipped.txt
index 4c456056fe9..22ba236f1fa 100644
--- a/src/Polly/PublicAPI.Shipped.txt
+++ b/src/Polly/PublicAPI.Shipped.txt
@@ -1052,3 +1052,9 @@ static readonly Polly.ExceptionPredicates.None -> Polly.ExceptionPredicates
 static readonly Polly.ResultPredicates<TResult>.None -> Polly.ResultPredicates<TResult>
 virtual Polly.AsyncPolicy.ImplementationAsync(System.Func<Polly.Context, System.Threading.CancellationToken, System.Threading.Tasks.Task> action, Polly.Context context, System.Threading.CancellationToken cancellationToken, bool continueOnCapturedContext) -> System.Threading.Tasks.Task
 virtual Polly.Policy.Implementation(System.Action<Polly.Context, System.Threading.CancellationToken> action, Polly.Context context, System.Threading.CancellationToken cancellationToken) -> void
+Polly.CircuitBreaker.BrokenCircuitException<TResult>
+Polly.CircuitBreaker.BrokenCircuitException<TResult>.BrokenCircuitException(string message, System.Exception inner, TResult result) -> void
+Polly.CircuitBreaker.BrokenCircuitException<TResult>.BrokenCircuitException(string message, TResult result) -> void
+Polly.CircuitBreaker.BrokenCircuitException<TResult>.BrokenCircuitException(TResult result) -> void
+Polly.CircuitBreaker.BrokenCircuitException<TResult>.Result.get -> TResult
+


Test patch:
diff --git a/test/Polly.Core.Tests/CircuitBreaker/BrokenCircuitExceptionTests.cs b/test/Polly.Core.Tests/CircuitBreaker/BrokenCircuitExceptionTests.cs
index 075e04b55f1..3fb989e7a59 100644
--- a/test/Polly.Core.Tests/CircuitBreaker/BrokenCircuitExceptionTests.cs
+++ b/test/Polly.Core.Tests/CircuitBreaker/BrokenCircuitExceptionTests.cs
@@ -12,39 +12,11 @@ public void Ctor_Ok()
         new BrokenCircuitException("Dummy.", new InvalidOperationException()).InnerException.Should().BeOfType<InvalidOperationException>();
     }
 
-    [Fact]
-    public void Ctor_Generic_Ok()
-    {
-        var exception = new BrokenCircuitException<int>(10);
-        exception.Result.Should().Be(10);
-
-        exception = new BrokenCircuitException<int>("Dummy.", 10);
-        exception.Message.Should().Be("Dummy.");
-        exception.Result.Should().Be(10);
-
-        exception = new BrokenCircuitException<int>("Dummy.", new InvalidOperationException(), 10);
-        exception.Message.Should().Be("Dummy.");
-        exception.Result.Should().Be(10);
-        exception.InnerException.Should().BeOfType<InvalidOperationException>();
-    }
-
 #if !NETCOREAPP
     [Fact]
     public void BinarySerialization_Ok()
     {
         BinarySerializationUtil.SerializeAndDeserializeException(new BrokenCircuitException()).Should().NotBeNull();
     }
-
-    [Fact]
-    public void BinarySerialization_Generic_Ok()
-    {
-        var result = BinarySerializationUtil
-            .SerializeAndDeserializeException(new BrokenCircuitException<int>(123));
-
-        result.Should().NotBeNull();
-
-        // default
-        result.Result.Should().Be(0);
-    }
 #endif
 }
diff --git a/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerResiliencePipelineBuilderTests.cs b/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerResiliencePipelineBuilderTests.cs
index d05ebf5914a..c9bb40cb017 100644
--- a/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerResiliencePipelineBuilderTests.cs
+++ b/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerResiliencePipelineBuilderTests.cs
@@ -11,7 +11,7 @@ public class CircuitBreakerResiliencePipelineBuilderTests
     {
         builder => builder.AddCircuitBreaker(new CircuitBreakerStrategyOptions
         {
-            ShouldHandle = _ => PredicateResult.True
+            ShouldHandle = _ => PredicateResult.True()
         }),
     };
 
@@ -19,7 +19,7 @@ public class CircuitBreakerResiliencePipelineBuilderTests
     {
         builder => builder.AddCircuitBreaker(new CircuitBreakerStrategyOptions<int>
         {
-            ShouldHandle = _ => PredicateResult.True
+            ShouldHandle = _ => PredicateResult.True()
         }),
     };
 
@@ -90,12 +90,12 @@ public void AddCircuitBreaker_IntegrationTest()
         opened.Should().Be(1);
         halfOpened.Should().Be(0);
         closed.Should().Be(0);
-        Assert.Throws<BrokenCircuitException<object>>(() => strategy.Execute(_ => 0));
+        Assert.Throws<BrokenCircuitException>(() => strategy.Execute(_ => 0));
 
         // Circuit Half Opened
         timeProvider.Advance(options.BreakDuration);
         strategy.Execute(_ => -1);
-        Assert.Throws<BrokenCircuitException<object>>(() => strategy.Execute(_ => 0));
+        Assert.Throws<BrokenCircuitException>(() => strategy.Execute(_ => 0));
         opened.Should().Be(2);
         halfOpened.Should().Be(1);
         closed.Should().Be(0);
diff --git a/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerResilienceStrategyTests.cs b/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerResilienceStrategyTests.cs
index fe0d54ee9e9..03c7d7c7658 100644
--- a/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerResilienceStrategyTests.cs
+++ b/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerResilienceStrategyTests.cs
@@ -123,7 +123,7 @@ public void Execute_UnhandledException_NoCalls()
     [Fact]
     public void Execute_Ok()
     {
-        _options.ShouldHandle = _ => PredicateResult.False;
+        _options.ShouldHandle = _ => PredicateResult.False();
 
         Create().Invoking(s => s.Execute(_ => 0)).Should().NotThrow();
 
diff --git a/test/Polly.Core.Tests/CircuitBreaker/Controller/CircuitStateControllerTests.cs b/test/Polly.Core.Tests/CircuitBreaker/Controller/CircuitStateControllerTests.cs
index 4e846e71385..75bcfc367d5 100644
--- a/test/Polly.Core.Tests/CircuitBreaker/Controller/CircuitStateControllerTests.cs
+++ b/test/Polly.Core.Tests/CircuitBreaker/Controller/CircuitStateControllerTests.cs
@@ -118,9 +118,8 @@ public async Task OnActionPreExecute_CircuitOpenedByValue()
         using var controller = CreateController();
 
         await OpenCircuit(controller, Outcome.FromResult(99));
-        var error = (BrokenCircuitException<int>)(await controller.OnActionPreExecuteAsync(ResilienceContextPool.Shared.Get())).Value.Exception!;
-        error.Should().BeOfType<BrokenCircuitException<int>>();
-        error.Result.Should().Be(99);
+        var error = (BrokenCircuitException)(await controller.OnActionPreExecuteAsync(ResilienceContextPool.Shared.Get())).Value.Exception!;
+        error.Should().BeOfType<BrokenCircuitException>();
 
         GetBlockedTill(controller).Should().Be(_timeProvider.GetUtcNow() + _options.BreakDuration);
     }
@@ -219,7 +218,7 @@ public async Task OnActionPreExecute_HalfOpen()
         // act
         await controller.OnActionPreExecuteAsync(ResilienceContextPool.Shared.Get());
         var error = (await controller.OnActionPreExecuteAsync(ResilienceContextPool.Shared.Get())).Value.Exception;
-        error.Should().BeOfType<BrokenCircuitException<int>>();
+        error.Should().BeOfType<BrokenCircuitException>();
 
         // assert
         controller.CircuitState.Should().Be(CircuitState.HalfOpen);
@@ -357,7 +356,7 @@ public async Task OnActionFailureAsync_VoidResult_EnsureBreakingExceptionNotSet(
         // assert
         controller.LastException.Should().BeNull();
         var outcome = await controller.OnActionPreExecuteAsync(ResilienceContextPool.Shared.Get());
-        outcome.Value.Exception.Should().BeOfType<BrokenCircuitException<int>>();
+        outcome.Value.Exception.Should().BeOfType<BrokenCircuitException>();
     }
 
     [Fact]
@@ -392,7 +391,7 @@ public async Task Flow_Closed_HalfOpen_Open_HalfOpen_Closed()
         // execution rejected
         AdvanceTime(TimeSpan.FromMilliseconds(1));
         var outcome = await controller.OnActionPreExecuteAsync(ResilienceContextPool.Shared.Get());
-        outcome.Value.Exception.Should().BeOfType<BrokenCircuitException<int>>();
+        outcome.Value.Exception.Should().BeOfType<BrokenCircuitException>();
 
         // wait and try, transition to half open
         AdvanceTime(_options.BreakDuration + _options.BreakDuration);
diff --git a/test/Polly.Core.Tests/Fallback/FallbackResiliencePipelineBuilderExtensionsTests.cs b/test/Polly.Core.Tests/Fallback/FallbackResiliencePipelineBuilderExtensionsTests.cs
index 5c601b34b91..6dbe198712d 100644
--- a/test/Polly.Core.Tests/Fallback/FallbackResiliencePipelineBuilderExtensionsTests.cs
+++ b/test/Polly.Core.Tests/Fallback/FallbackResiliencePipelineBuilderExtensionsTests.cs
@@ -12,8 +12,8 @@ public class FallbackResiliencePipelineBuilderExtensionsTests
         {
             builder.AddFallback(new FallbackStrategyOptions<int>
             {
-                FallbackAction = _ => Outcome.FromResultAsTask(0),
-                ShouldHandle = _ => PredicateResult.False,
+                FallbackAction = _ => Outcome.FromResultAsValueTask(0),
+                ShouldHandle = _ => PredicateResult.False(),
             });
         }
     };
diff --git a/test/Polly.Core.Tests/Fallback/FallbackResilienceStrategyTests.cs b/test/Polly.Core.Tests/Fallback/FallbackResilienceStrategyTests.cs
index 0e0cbad4ab9..8415d82e19d 100644
--- a/test/Polly.Core.Tests/Fallback/FallbackResilienceStrategyTests.cs
+++ b/test/Polly.Core.Tests/Fallback/FallbackResilienceStrategyTests.cs
@@ -52,7 +52,7 @@ public void ShouldHandle_ArgumentsSetCorrectly(bool handle)
                 args.Outcome.Result.Should().Be("ok");
                 args.Context.Should().NotBeNull();
                 called++;
-                return Outcome.FromResultAsTask("fallback");
+                return Outcome.FromResultAsValueTask("fallback");
             });
 
         var result = Create().Execute(_ => "ok");
diff --git a/test/Polly.Core.Tests/Hedging/Controller/HedgingControllerTests.cs b/test/Polly.Core.Tests/Hedging/Controller/HedgingControllerTests.cs
index 33927630462..e31fffc15b1 100644
--- a/test/Polly.Core.Tests/Hedging/Controller/HedgingControllerTests.cs
+++ b/test/Polly.Core.Tests/Hedging/Controller/HedgingControllerTests.cs
@@ -28,7 +28,7 @@ public async Task Pooling_Ok()
 
     private static async Task PrepareAsync(HedgingExecutionContext<int> context)
     {
-        await context.LoadExecutionAsync((_, _) => Outcome.FromResultAsTask(10), "state");
+        await context.LoadExecutionAsync((_, _) => Outcome.FromResultAsValueTask(10), "state");
         await context.TryWaitForCompletedExecutionAsync(System.Threading.Timeout.InfiniteTimeSpan);
         context.Tasks[0].AcceptOutcome();
     }
diff --git a/test/Polly.Core.Tests/Hedging/Controller/HedgingExecutionContextTests.cs b/test/Polly.Core.Tests/Hedging/Controller/HedgingExecutionContextTests.cs
index bbd20da0eb9..8c0a2700e2d 100644
--- a/test/Polly.Core.Tests/Hedging/Controller/HedgingExecutionContextTests.cs
+++ b/test/Polly.Core.Tests/Hedging/Controller/HedgingExecutionContextTests.cs
@@ -97,7 +97,7 @@ public async Task TryWaitForCompletedExecutionAsync_FinishedTask_Ok()
     {
         var context = Create();
         context.Initialize(_resilienceContext);
-        await context.LoadExecutionAsync((_, _) => Outcome.FromResultAsTask(new DisposableResult("dummy")), "state");
+        await context.LoadExecutionAsync((_, _) => Outcome.FromResultAsValueTask(new DisposableResult("dummy")), "state");
 
         var task = await context.TryWaitForCompletedExecutionAsync(TimeSpan.Zero);
 
@@ -182,8 +182,8 @@ public async Task TryWaitForCompletedExecutionAsync_TwiceWhenSecondaryGeneratorN
 
         var context = Create();
         context.Initialize(_resilienceContext);
-        await context.LoadExecutionAsync((_, _) => Outcome.FromResultAsTask(new DisposableResult("dummy")), "state");
-        await context.LoadExecutionAsync((_, _) => Outcome.FromResultAsTask(new DisposableResult("dummy")), "state");
+        await context.LoadExecutionAsync((_, _) => Outcome.FromResultAsValueTask(new DisposableResult("dummy")), "state");
+        await context.LoadExecutionAsync((_, _) => Outcome.FromResultAsValueTask(new DisposableResult("dummy")), "state");
 
         var task = await context.TryWaitForCompletedExecutionAsync(TimeSpan.Zero);
 
@@ -199,7 +199,7 @@ public async Task TryWaitForCompletedExecutionAsync_TwiceWhenSecondaryGeneratorR
         await LoadExecutionAsync(context);
         await LoadExecutionAsync(context);
 
-        Generator = args => () => Outcome.FromResultAsTask(new DisposableResult { Name = "secondary" });
+        Generator = args => () => Outcome.FromResultAsValueTask(new DisposableResult { Name = "secondary" });
 
         var task = await context.TryWaitForCompletedExecutionAsync(TimeSpan.Zero);
         task!.Type.Should().Be(HedgedTaskType.Primary);
@@ -470,7 +470,7 @@ private void ConfigureSecondaryTasks(params TimeSpan[] delays)
 
     private Func<HedgingActionGeneratorArguments<DisposableResult>, Func<ValueTask<Outcome<DisposableResult>>>?> Generator { get; set; } = args =>
     {
-        return () => Outcome.FromResultAsTask(new DisposableResult { Name = Handled });
+        return () => Outcome.FromResultAsValueTask(new DisposableResult { Name = Handled });
     };
 
     private HedgingExecutionContext<DisposableResult> Create()
diff --git a/test/Polly.Core.Tests/Hedging/Controller/TaskExecutionTests.cs b/test/Polly.Core.Tests/Hedging/Controller/TaskExecutionTests.cs
index 760831a6b66..fa7ec8280c8 100644
--- a/test/Polly.Core.Tests/Hedging/Controller/TaskExecutionTests.cs
+++ b/test/Polly.Core.Tests/Hedging/Controller/TaskExecutionTests.cs
@@ -52,7 +52,7 @@ await execution.InitializeAsync(HedgedTaskType.Primary, _snapshot,
             {
                 AssertPrimaryContext(context, execution);
                 state.Should().Be("dummy-state");
-                return Outcome.FromResultAsTask(new DisposableResult { Name = value });
+                return Outcome.FromResultAsValueTask(new DisposableResult { Name = value });
             },
             "dummy-state",
             99);
@@ -91,7 +91,7 @@ public async Task Initialize_Secondary_Ok(string value, bool handled)
         {
             AssertSecondaryContext(args.ActionContext, execution);
             args.AttemptNumber.Should().Be(4);
-            return () => Outcome.FromResultAsTask(new DisposableResult { Name = value });
+            return () => Outcome.FromResultAsValueTask(new DisposableResult { Name = value });
         };
 
         (await execution.InitializeAsync<string>(HedgedTaskType.Secondary, _snapshot, null!, "dummy-state", 4)).Should().BeTrue();
@@ -255,7 +255,7 @@ private async Task InitializePrimaryAsync(TaskExecution<DisposableResult> execut
         await execution.InitializeAsync(HedgedTaskType.Primary, _snapshot, (context, _) =>
         {
             onContext?.Invoke(context);
-            return Outcome.FromResultAsTask(result ?? new DisposableResult { Name = Handled });
+            return Outcome.FromResultAsValueTask(result ?? new DisposableResult { Name = Handled });
         }, "dummy-state", 1);
     }
 
@@ -296,7 +296,7 @@ private void CreateSnapshot(CancellationToken? token = null)
 
     private Func<HedgingActionGeneratorArguments<DisposableResult>, Func<ValueTask<Outcome<DisposableResult>>>?> Generator { get; set; } = args =>
     {
-        return () => Outcome.FromResultAsTask(new DisposableResult { Name = Handled });
+        return () => Outcome.FromResultAsValueTask(new DisposableResult { Name = Handled });
     };
 
     private TaskExecution<DisposableResult> Create() => new(_hedgingHandler, CancellationTokenSourcePool.Create(TimeProvider.System), _timeProvider, _telemetry);
diff --git a/test/Polly.Core.Tests/Hedging/HedgingActionGeneratorArgumentsTests.cs b/test/Polly.Core.Tests/Hedging/HedgingActionGeneratorArgumentsTests.cs
index 0c871989a16..8de0f80fd97 100644
--- a/test/Polly.Core.Tests/Hedging/HedgingActionGeneratorArgumentsTests.cs
+++ b/test/Polly.Core.Tests/Hedging/HedgingActionGeneratorArgumentsTests.cs
@@ -7,7 +7,7 @@ public class HedgingActionGeneratorArgumentsTests
     [Fact]
     public void Ctor_Ok()
     {
-        var args = new HedgingActionGeneratorArguments<string>(ResilienceContextPool.Shared.Get(), ResilienceContextPool.Shared.Get(), 5, _ => Outcome.FromResultAsTask("dummy"));
+        var args = new HedgingActionGeneratorArguments<string>(ResilienceContextPool.Shared.Get(), ResilienceContextPool.Shared.Get(), 5, _ => Outcome.FromResultAsValueTask("dummy"));
 
         args.PrimaryContext.Should().NotBeNull();
         args.ActionContext.Should().NotBeNull();
diff --git a/test/Polly.Core.Tests/Hedging/HedgingHandlerTests.cs b/test/Polly.Core.Tests/Hedging/HedgingHandlerTests.cs
index 45baab8fdc4..2f988c279b1 100644
--- a/test/Polly.Core.Tests/Hedging/HedgingHandlerTests.cs
+++ b/test/Polly.Core.Tests/Hedging/HedgingHandlerTests.cs
@@ -9,14 +9,14 @@ public class HedgingHandlerTests
     public async Task GenerateAction_Generic_Ok()
     {
         var handler = new HedgingHandler<string>(
-            args => PredicateResult.True,
-            args => () => Outcome.FromResultAsTask("ok"));
+            args => PredicateResult.True(),
+            args => () => Outcome.FromResultAsValueTask("ok"));
 
         var action = handler.GenerateAction(new HedgingActionGeneratorArguments<string>(
             ResilienceContextPool.Shared.Get(),
             ResilienceContextPool.Shared.Get(),
             0,
-            _ => Outcome.FromResultAsTask("primary")))!;
+            _ => Outcome.FromResultAsValueTask("primary")))!;
         var res = await action();
 
         res.Result.Should().Be("ok");
diff --git a/test/Polly.Core.Tests/Hedging/HedgingResiliencePipelineBuilderExtensionsTests.cs b/test/Polly.Core.Tests/Hedging/HedgingResiliencePipelineBuilderExtensionsTests.cs
index bfa2f2b02e5..13e877146f2 100644
--- a/test/Polly.Core.Tests/Hedging/HedgingResiliencePipelineBuilderExtensionsTests.cs
+++ b/test/Polly.Core.Tests/Hedging/HedgingResiliencePipelineBuilderExtensionsTests.cs
@@ -14,8 +14,8 @@ public void AddHedging_Generic_Ok()
     {
         _builder.AddHedging(new HedgingStrategyOptions<string>
         {
-            ActionGenerator = args => () => Outcome.FromResultAsTask("dummy"),
-            ShouldHandle = _ => PredicateResult.True
+            ActionGenerator = args => () => Outcome.FromResultAsValueTask("dummy"),
+            ShouldHandle = _ => PredicateResult.True()
         });
 
         _builder.Build().GetPipelineDescriptor().FirstStrategy.StrategyInstance
@@ -45,8 +45,8 @@ public async Task AddHedging_IntegrationTest()
                 Delay = TimeSpan.FromMilliseconds(20),
                 ShouldHandle = args => args.Outcome.Result switch
                 {
-                    "error" => PredicateResult.True,
-                    _ => PredicateResult.False
+                    "error" => PredicateResult.True(),
+                    _ => PredicateResult.False()
                 },
                 ActionGenerator = args =>
                 {
diff --git a/test/Polly.Core.Tests/Hedging/HedgingResilienceStrategyTests.cs b/test/Polly.Core.Tests/Hedging/HedgingResilienceStrategyTests.cs
index efc80efd2c9..82e757c0738 100644
--- a/test/Polly.Core.Tests/Hedging/HedgingResilienceStrategyTests.cs
+++ b/test/Polly.Core.Tests/Hedging/HedgingResilienceStrategyTests.cs
@@ -65,7 +65,7 @@ public async Task Execute_CancellationRequested_Throws()
         var context = ResilienceContextPool.Shared.Get();
         context.CancellationToken = _cts.Token;
 
-        var outcome = await strategy.ExecuteCore((_, _) => Outcome.FromResultAsTask("dummy"), context, "state");
+        var outcome = await strategy.ExecuteCore((_, _) => Outcome.FromResultAsValueTask("dummy"), context, "state");
         outcome.Exception.Should().BeOfType<OperationCanceledException>();
         outcome.Exception!.StackTrace.Should().Contain("Execute_CancellationRequested_Throws");
     }
@@ -80,7 +80,7 @@ public void ExecutePrimaryAndSecondary_EnsureAttemptReported()
             return timeStamp;
         };
         _options.MaxHedgedAttempts = 2;
-        ConfigureHedging(_ => true, args => () => Outcome.FromResultAsTask("any"));
+        ConfigureHedging(_ => true, args => () => Outcome.FromResultAsValueTask("any"));
         var strategy = Create();
 
         strategy.Execute(_ => "dummy");
@@ -101,7 +101,7 @@ public async Task ExecutePrimary_Cancelled_SecondaryShouldBeExecuted()
     {
         _options.MaxHedgedAttempts = 2;
 
-        ConfigureHedging(o => o.Result == "primary", args => () => Outcome.FromResultAsTask("secondary"));
+        ConfigureHedging(o => o.Result == "primary", args => () => Outcome.FromResultAsValueTask("secondary"));
         var strategy = Create();
 
         var result = await strategy.ExecuteAsync(
@@ -186,7 +186,7 @@ public async Task ExecuteAsync_EnsurePrimaryContextFlows()
         {
             args.PrimaryContext.Properties.GetValue(key, string.Empty).Should().Be("dummy");
             args.PrimaryContext.Should().Be(primaryContext);
-            return () => Outcome.FromResultAsTask(Failure);
+            return () => Outcome.FromResultAsValueTask(Failure);
         });
 
         var strategy = Create();
@@ -298,7 +298,7 @@ public async Task ExecuteAsync_EnsureSecondaryHedgedTaskReportedWithNoOutcome()
             return default;
         };
 
-        ConfigureHedging(context => Outcome.FromResultAsTask(Success));
+        ConfigureHedging(context => Outcome.FromResultAsValueTask(Success));
 
         var strategy = Create();
 
@@ -326,7 +326,7 @@ public async Task ExecuteAsync_EnsureDiscardedResultDisposed()
         {
             return () =>
             {
-                return Outcome.FromResultAsTask(secondaryResult);
+                return Outcome.FromResultAsValueTask(secondaryResult);
             };
         });
 
@@ -530,7 +530,7 @@ public async Task ExecuteAsync_Secondary_CustomPropertiesAvailable()
                 args.ActionContext.Properties.TryGetValue(key2, out var val).Should().BeTrue();
                 val.Should().Be("my-value-2");
                 args.ActionContext.Properties.Set(key, "my-value");
-                return Outcome.FromResultAsTask(Success);
+                return Outcome.FromResultAsValueTask(Success);
             };
         });
         var strategy = Create();
@@ -549,7 +549,7 @@ public async Task ExecuteAsync_Secondary_CustomPropertiesAvailable()
     public async Task ExecuteAsync_OnHedgingEventThrows_EnsureExceptionRethrown()
     {
         // arrange
-        ConfigureHedging(args => () => Outcome.FromResultAsTask(Success));
+        ConfigureHedging(args => () => Outcome.FromResultAsValueTask(Success));
         _options.OnHedging = _ => throw new InvalidOperationException("my-exception");
         var strategy = Create();
 
@@ -651,7 +651,7 @@ ValueTask<Outcome<string>> BackgroundWork(ResilienceContext resilienceContext)
         {
             var delay = Task.Delay(TimeSpan.FromDays(24), resilienceContext.CancellationToken);
             backgroundTasks.Add(delay);
-            return Outcome.FromResultAsTask(Success);
+            return Outcome.FromResultAsValueTask(Success);
         }
     }
 
@@ -833,10 +833,10 @@ public async Task ExecuteAsync_ExceptionsHandled_ShouldReturnLastResult()
                 {
                     if (exception != null)
                     {
-                        return Outcome.FromExceptionAsTask<string>(exception);
+                        return Outcome.FromExceptionAsValueTask<string>(exception);
                     }
 
-                    return Outcome.FromResultAsTask(Success);
+                    return Outcome.FromResultAsValueTask(Success);
                 };
             });
 
@@ -851,7 +851,7 @@ public async Task ExecuteAsync_EnsureHedgingDelayGeneratorRespected()
         var delay = TimeSpan.FromMilliseconds(12345);
         _options.DelayGenerator = _ => new ValueTask<TimeSpan>(TimeSpan.FromMilliseconds(12345));
 
-        ConfigureHedging(res => false, args => () => Outcome.FromResultAsTask(Success));
+        ConfigureHedging(res => false, args => () => Outcome.FromResultAsValueTask(Success));
 
         var strategy = Create();
         var task = strategy.ExecuteAsync<string>(async token =>
@@ -892,7 +892,7 @@ public async Task ExecuteAsync_EnsureOnHedgingCalled()
             return default;
         };
 
-        ConfigureHedging(res => res.Result == Failure, args => () => Outcome.FromResultAsTask(Failure));
+        ConfigureHedging(res => res.Result == Failure, args => () => Outcome.FromResultAsValueTask(Failure));
 
         var strategy = Create();
         await strategy.ExecuteAsync(_ => new ValueTask<string>(Failure));
@@ -907,7 +907,7 @@ public async Task ExecuteAsync_EnsureOnHedgingTelemetry()
     {
         var context = ResilienceContextPool.Shared.Get();
 
-        ConfigureHedging(res => res.Result == Failure, args => () => Outcome.FromResultAsTask(Failure));
+        ConfigureHedging(res => res.Result == Failure, args => () => Outcome.FromResultAsValueTask(Failure));
 
         var strategy = Create();
         await strategy.ExecuteAsync((_, _) => new ValueTask<string>(Failure), context, "state");
diff --git a/test/Polly.Core.Tests/Hedging/HedgingStrategyOptionsTests.cs b/test/Polly.Core.Tests/Hedging/HedgingStrategyOptionsTests.cs
index 2208428f689..51d02dcd240 100644
--- a/test/Polly.Core.Tests/Hedging/HedgingStrategyOptionsTests.cs
+++ b/test/Polly.Core.Tests/Hedging/HedgingStrategyOptionsTests.cs
@@ -39,7 +39,7 @@ public async Task HedgingActionGenerator_EnsureDefaults(bool synchronous)
                 Thread.CurrentThread.ManagedThreadId.Should().Be(threadId);
             }
 
-            return Outcome.FromResultAsTask(99);
+            return Outcome.FromResultAsValueTask(99);
         }))!;
 
         action.Should().NotBeNull();
diff --git a/test/Polly.Core.Tests/Issues/IssuesTests.FlowingContext_849.cs b/test/Polly.Core.Tests/Issues/IssuesTests.FlowingContext_849.cs
index 7b1a829e4db..55e39f54acd 100644
--- a/test/Polly.Core.Tests/Issues/IssuesTests.FlowingContext_849.cs
+++ b/test/Polly.Core.Tests/Issues/IssuesTests.FlowingContext_849.cs
@@ -18,7 +18,7 @@ public void FlowingContext_849()
                     ResilienceContext context = args.Context;
                     context.Should().NotBeNull();
                     contextChecked = true;
-                    return PredicateResult.False;
+                    return PredicateResult.False();
                 }
             })
             .Build();
diff --git a/test/Polly.Core.Tests/Issues/IssuesTests.HandleMultipleResults_898.cs b/test/Polly.Core.Tests/Issues/IssuesTests.HandleMultipleResults_898.cs
index 3065826d2e1..9dfc01af8b2 100644
--- a/test/Polly.Core.Tests/Issues/IssuesTests.HandleMultipleResults_898.cs
+++ b/test/Polly.Core.Tests/Issues/IssuesTests.HandleMultipleResults_898.cs
@@ -16,11 +16,11 @@ public void HandleMultipleResults_898()
             ShouldHandle = args => args.Outcome switch
             {
                 // handle string results
-                { Result: string res } when res == "error" => PredicateResult.True,
+                { Result: string res } when res == "error" => PredicateResult.True(),
 
                 // handle int results
-                { Result: int res } when res == -1 => PredicateResult.True,
-                _ => PredicateResult.False
+                { Result: int res } when res == -1 => PredicateResult.True(),
+                _ => PredicateResult.False()
             },
             OnRetry = args =>
             {
diff --git a/test/Polly.Core.Tests/OutcomeTests.cs b/test/Polly.Core.Tests/OutcomeTests.cs
index 4474a652b0a..42e2c1dfc02 100644
--- a/test/Polly.Core.Tests/OutcomeTests.cs
+++ b/test/Polly.Core.Tests/OutcomeTests.cs
@@ -50,7 +50,7 @@ public void EnsureSuccess_Result()
     {
         var outcome = Outcome.FromResult("dummy");
 
-        outcome.Invoking(o => o.EnsureSuccess()).Should().NotThrow();
+        outcome.Invoking(o => o.ThrowIfException()).Should().NotThrow();
     }
 
     [Fact]
@@ -58,6 +58,6 @@ public void EnsureSuccess_Exception()
     {
         var outcome = Outcome.FromException<string>(new InvalidOperationException());
 
-        outcome.Invoking(o => o.EnsureSuccess()).Should().Throw<InvalidOperationException>();
+        outcome.Invoking(o => o.ThrowIfException()).Should().Throw<InvalidOperationException>();
     }
 }
diff --git a/test/Polly.Core.Tests/PredicateResultTests.cs b/test/Polly.Core.Tests/PredicateResultTests.cs
index f1a48c0cdca..a3a655fcc8d 100644
--- a/test/Polly.Core.Tests/PredicateResultTests.cs
+++ b/test/Polly.Core.Tests/PredicateResultTests.cs
@@ -5,12 +5,12 @@ public class PredicateResultTests
     [Fact]
     public async Task True_Ok()
     {
-        (await PredicateResult.True).Should().BeTrue();
+        (await PredicateResult.True()).Should().BeTrue();
     }
 
     [Fact]
     public async Task False_Ok()
     {
-        (await PredicateResult.False).Should().BeFalse();
+        (await PredicateResult.False()).Should().BeFalse();
     }
 }
diff --git a/test/Polly.Core.Tests/Registry/ResiliencePipelineRegistryTests.cs b/test/Polly.Core.Tests/Registry/ResiliencePipelineRegistryTests.cs
index 4968d635155..ea89af60a89 100644
--- a/test/Polly.Core.Tests/Registry/ResiliencePipelineRegistryTests.cs
+++ b/test/Polly.Core.Tests/Registry/ResiliencePipelineRegistryTests.cs
@@ -268,7 +268,7 @@ public void EnableReloads_Ok(bool firstOne)
 
             builder.AddRetry(new RetryStrategyOptions
             {
-                ShouldHandle = _ => PredicateResult.True,
+                ShouldHandle = _ => PredicateResult.True(),
                 MaxRetryAttempts = retryCount,
                 Delay = TimeSpan.FromMilliseconds(2),
             });
@@ -344,7 +344,7 @@ public void EnableReloads_Generic_Ok()
 
             builder.AddRetry(new RetryStrategyOptions<string>
             {
-                ShouldHandle = _ => PredicateResult.True,
+                ShouldHandle = _ => PredicateResult.True(),
                 MaxRetryAttempts = retryCount,
                 Delay = TimeSpan.FromMilliseconds(2),
             });
diff --git a/test/Polly.Core.Tests/ResiliencePipelineTTests.Async.cs b/test/Polly.Core.Tests/ResiliencePipelineTTests.Async.cs
index 27dcd6a46b9..333a4d22034 100644
--- a/test/Polly.Core.Tests/ResiliencePipelineTTests.Async.cs
+++ b/test/Polly.Core.Tests/ResiliencePipelineTTests.Async.cs
@@ -87,7 +87,7 @@ public async Task ExecuteOutcomeAsync_GenericStrategy_Ok()
             state.Should().Be("state");
             context.IsSynchronous.Should().BeFalse();
             context.ResultType.Should().Be(typeof(int));
-            return Outcome.FromResultAsTask(12345);
+            return Outcome.FromResultAsValueTask(12345);
         },
         ResilienceContextPool.Shared.Get(),
         "state");
diff --git a/test/Polly.Core.Tests/ResiliencePipelineTests.AsyncT.cs b/test/Polly.Core.Tests/ResiliencePipelineTests.AsyncT.cs
index 1ae26be6741..99bf972b03c 100644
--- a/test/Polly.Core.Tests/ResiliencePipelineTests.AsyncT.cs
+++ b/test/Polly.Core.Tests/ResiliencePipelineTests.AsyncT.cs
@@ -122,7 +122,7 @@ public async Task ExecuteOutcomeAsync_Ok()
             state.Should().Be("state");
             context.IsSynchronous.Should().BeFalse();
             context.ResultType.Should().Be(typeof(int));
-            return Outcome.FromResultAsTask(12345);
+            return Outcome.FromResultAsValueTask(12345);
         },
         ResilienceContextPool.Shared.Get(),
         "state");
diff --git a/test/Polly.Core.Tests/Retry/RetryDelayGeneratorArgumentsTests.cs b/test/Polly.Core.Tests/Retry/RetryDelayGeneratorArgumentsTests.cs
index f02558e023e..5fb9dee6276 100644
--- a/test/Polly.Core.Tests/Retry/RetryDelayGeneratorArgumentsTests.cs
+++ b/test/Polly.Core.Tests/Retry/RetryDelayGeneratorArgumentsTests.cs
@@ -7,11 +7,10 @@ public class RetryDelayGeneratorArgumentsTests
     [Fact]
     public void Ctor_Ok()
     {
-        var args = new RetryDelayGeneratorArguments<int>(ResilienceContextPool.Shared.Get(), Outcome.FromResult(1), 2, TimeSpan.FromSeconds(2));
+        var args = new RetryDelayGeneratorArguments<int>(ResilienceContextPool.Shared.Get(), Outcome.FromResult(1), 2);
 
         args.Context.Should().NotBeNull();
         args.Outcome.Result.Should().Be(1);
         args.AttemptNumber.Should().Be(2);
-        args.DelayHint.Should().Be(TimeSpan.FromSeconds(2));
     }
 }
diff --git a/test/Polly.Core.Tests/Retry/RetryResiliencePipelineBuilderExtensionsTests.cs b/test/Polly.Core.Tests/Retry/RetryResiliencePipelineBuilderExtensionsTests.cs
index 57a0010e371..f73886985ba 100644
--- a/test/Polly.Core.Tests/Retry/RetryResiliencePipelineBuilderExtensionsTests.cs
+++ b/test/Polly.Core.Tests/Retry/RetryResiliencePipelineBuilderExtensionsTests.cs
@@ -1,4 +1,5 @@
 using System.ComponentModel.DataAnnotations;
+using NSubstitute;
 using Polly.Retry;
 using Polly.Testing;
 
@@ -17,7 +18,7 @@ public class RetryResiliencePipelineBuilderExtensionsTests
                 BackoffType = DelayBackoffType.Exponential,
                 MaxRetryAttempts = 3,
                 Delay = TimeSpan.FromSeconds(2),
-                ShouldHandle = _ => PredicateResult.True,
+                ShouldHandle = _ => PredicateResult.True(),
             });
 
             AssertStrategy(builder, DelayBackoffType.Exponential, 3, TimeSpan.FromSeconds(2));
@@ -33,7 +34,7 @@ public class RetryResiliencePipelineBuilderExtensionsTests
                 BackoffType = DelayBackoffType.Exponential,
                 MaxRetryAttempts = 3,
                 Delay = TimeSpan.FromSeconds(2),
-                ShouldHandle = _ => PredicateResult.True
+                ShouldHandle = _ => PredicateResult.True()
             });
 
             AssertStrategy(builder, DelayBackoffType.Exponential, 3, TimeSpan.FromSeconds(2));
@@ -62,7 +63,7 @@ public void AddRetry_GenericOverloads_Ok(Action<ResiliencePipelineBuilder<int>>
     public void AddRetry_DefaultOptions_Ok()
     {
         var builder = new ResiliencePipelineBuilder();
-        var options = new RetryStrategyOptions { ShouldHandle = _ => PredicateResult.True };
+        var options = new RetryStrategyOptions { ShouldHandle = _ => PredicateResult.True() };
 
         builder.AddRetry(options);
 
@@ -131,19 +132,18 @@ private static TimeSpan GetAggregatedDelay<T>(RetryStrategyOptions<T> options)
     {
         var aggregatedDelay = TimeSpan.Zero;
 
-        var strategy = new ResiliencePipelineBuilder().AddRetry(new()
+        var strategy = new ResiliencePipelineBuilder { TimeProvider = new NoWaitingTimeProvider() }.AddRetry(new()
         {
             MaxRetryAttempts = options.MaxRetryAttempts,
             Delay = options.Delay,
             BackoffType = options.BackoffType,
-            ShouldHandle = _ => PredicateResult.True, // always retry until all retries are exhausted
-            DelayGenerator = args =>
+            ShouldHandle = _ => PredicateResult.True(), // always retry until all retries are exhausted
+            OnRetry = args =>
             {
                 // the delay hint is calculated for this attempt by the retry strategy
-                aggregatedDelay += args.DelayHint;
+                aggregatedDelay += args.RetryDelay;
 
-                // return zero delay, so no waiting
-                return new ValueTask<TimeSpan>(TimeSpan.Zero);
+                return default;
             },
             Randomizer = () => 1.0,
         })
@@ -154,4 +154,13 @@ private static TimeSpan GetAggregatedDelay<T>(RetryStrategyOptions<T> options)
 
         return aggregatedDelay;
     }
+
+    private class NoWaitingTimeProvider : TimeProvider
+    {
+        public override ITimer CreateTimer(TimerCallback callback, object? state, TimeSpan dueTime, TimeSpan period)
+        {
+            callback(state);
+            return Substitute.For<ITimer>();
+        }
+    }
 }
diff --git a/test/Polly.Core.Tests/Retry/RetryResilienceStrategyTests.cs b/test/Polly.Core.Tests/Retry/RetryResilienceStrategyTests.cs
index 4f05e5b3dc6..3e209ffa5cf 100644
--- a/test/Polly.Core.Tests/Retry/RetryResilienceStrategyTests.cs
+++ b/test/Polly.Core.Tests/Retry/RetryResilienceStrategyTests.cs
@@ -40,7 +40,7 @@ public async Task ExecuteAsync_CancellationRequested_EnsureNotRetried()
         context.CancellationToken = cancellationToken.Token;
         var executed = false;
 
-        var result = await sut.ExecuteOutcomeAsync((_, _) => { executed = true; return Outcome.FromResultAsTask("dummy"); }, context, "state");
+        var result = await sut.ExecuteOutcomeAsync((_, _) => { executed = true; return Outcome.FromResultAsValueTask("dummy"); }, context, "state");
         result.Exception.Should().BeOfType<OperationCanceledException>();
         executed.Should().BeFalse();
     }
@@ -50,7 +50,7 @@ public async Task ExecuteAsync_CancellationRequestedAfterCallback_EnsureNotRetri
     {
         using var cancellationToken = new CancellationTokenSource();
 
-        _options.ShouldHandle = _ => PredicateResult.True;
+        _options.ShouldHandle = _ => PredicateResult.True();
         _options.OnRetry = _ =>
         {
             cancellationToken.Cancel();
@@ -62,7 +62,7 @@ public async Task ExecuteAsync_CancellationRequestedAfterCallback_EnsureNotRetri
         context.CancellationToken = cancellationToken.Token;
         var executed = false;
 
-        var result = await sut.ExecuteOutcomeAsync((_, _) => { executed = true; return Outcome.FromResultAsTask("dummy"); }, context, "state");
+        var result = await sut.ExecuteOutcomeAsync((_, _) => { executed = true; return Outcome.FromResultAsValueTask("dummy"); }, context, "state");
         result.Exception.Should().BeOfType<OperationCanceledException>();
         executed.Should().BeTrue();
     }
@@ -73,7 +73,7 @@ public void ExecuteAsync_MultipleRetries_EnsureDiscardedResultsDisposed()
         // arrange
         _options.MaxRetryAttempts = 5;
         SetupNoDelay();
-        _options.ShouldHandle = _ => PredicateResult.True;
+        _options.ShouldHandle = _ => PredicateResult.True();
         var results = new List<DisposableResult>();
         var sut = CreateSut();
 
@@ -137,7 +137,7 @@ public void RetryDelayGenerator_Respected()
         var generatedValues = 0;
         var delay = TimeSpan.FromMilliseconds(120);
 
-        _options.ShouldHandle = _ => PredicateResult.True;
+        _options.ShouldHandle = _ => PredicateResult.True();
         _options.MaxRetryAttempts = 3;
         _options.BackoffType = DelayBackoffType.Constant;
 
@@ -150,7 +150,7 @@ public void RetryDelayGenerator_Respected()
         _options.DelayGenerator = _ =>
         {
             generatedValues++;
-            return new ValueTask<TimeSpan>(delay);
+            return new ValueTask<TimeSpan?>(delay);
         };
 
         CreateSut(TimeProvider.System).Execute<string>(_ => "dummy");
@@ -168,7 +168,7 @@ public async Task RetryDelayGenerator_ZeroDelay_NoTimeProviderCalls()
         var delay = TimeSpan.Zero;
         var provider = new ThrowingFakeTimeProvider();
 
-        _options.ShouldHandle = _ => PredicateResult.True;
+        _options.ShouldHandle = _ => PredicateResult.True();
         _options.MaxRetryAttempts = 3;
         _options.BackoffType = DelayBackoffType.Constant;
 
@@ -180,7 +180,7 @@ public async Task RetryDelayGenerator_ZeroDelay_NoTimeProviderCalls()
         _options.DelayGenerator = _ =>
         {
             generatedValues++;
-            return new ValueTask<TimeSpan>(delay);
+            return new ValueTask<TimeSpan?>(delay);
         };
 
         var sut = CreateSut(provider);
@@ -213,7 +213,7 @@ public async void OnRetry_EnsureCorrectArguments()
             return default;
         };
 
-        _options.ShouldHandle = args => PredicateResult.True;
+        _options.ShouldHandle = args => PredicateResult.True();
         _options.MaxRetryAttempts = 3;
         _options.BackoffType = DelayBackoffType.Linear;
 
@@ -243,7 +243,7 @@ public async Task OnRetry_EnsureExecutionTime()
             return default;
         };
 
-        _options.ShouldHandle = _ => PredicateResult.True;
+        _options.ShouldHandle = _ => PredicateResult.True();
         _options.MaxRetryAttempts = 1;
         _options.BackoffType = DelayBackoffType.Constant;
         _options.Delay = TimeSpan.Zero;
@@ -307,12 +307,11 @@ public void RetryDelayGenerator_EnsureCorrectArguments()
         _options.DelayGenerator = args =>
         {
             attempts.Add(args.AttemptNumber);
-            hints.Add(args.DelayHint);
 
             args.Outcome.Exception.Should().BeNull();
             args.Outcome.Result.Should().Be(0);
 
-            return new ValueTask<TimeSpan>(TimeSpan.Zero);
+            return new ValueTask<TimeSpan?>(TimeSpan.Zero);
         };
 
         _options.ShouldHandle = args => args.Outcome.ResultPredicateAsync(0);
@@ -327,13 +326,33 @@ public void RetryDelayGenerator_EnsureCorrectArguments()
         attempts[0].Should().Be(0);
         attempts[1].Should().Be(1);
         attempts[2].Should().Be(2);
+    }
+
+    [Fact]
+    public void RetryDelayGenerator_ReturnsNull_EnsureDefaultRetry()
+    {
+        var delays = new List<TimeSpan>();
+        _options.DelayGenerator = args => new ValueTask<TimeSpan?>((TimeSpan?)null);
+        _options.OnRetry = args =>
+        {
+            delays.Add(args.RetryDelay);
+            return default;
+        };
+        _options.ShouldHandle = args => args.Outcome.ResultPredicateAsync(0);
+        _options.MaxRetryAttempts = 2;
+        _options.BackoffType = DelayBackoffType.Constant;
+        _options.Delay = TimeSpan.FromMilliseconds(2);
+
+        var sut = CreateSut(TimeProvider.System);
+
+        sut.Execute(() => 0);
 
-        hints[0].Should().Be(TimeSpan.FromSeconds(2));
-        hints[1].Should().Be(TimeSpan.FromSeconds(4));
-        hints[2].Should().Be(TimeSpan.FromSeconds(6));
+        delays.Should().HaveCount(2);
+        delays[0].Should().Be(TimeSpan.FromMilliseconds(2));
+        delays[1].Should().Be(TimeSpan.FromMilliseconds(2));
     }
 
-    private void SetupNoDelay() => _options.DelayGenerator = _ => new ValueTask<TimeSpan>(TimeSpan.Zero);
+    private void SetupNoDelay() => _options.DelayGenerator = _ => new ValueTask<TimeSpan?>(TimeSpan.Zero);
 
     private async ValueTask<int> ExecuteAndAdvance(ResiliencePipeline<object> sut)
     {
diff --git a/test/Polly.Core.Tests/Utils/Pipeline/CompositePipelineComponentTests.cs b/test/Polly.Core.Tests/Utils/Pipeline/CompositePipelineComponentTests.cs
index 324952e67bc..77529774d78 100644
--- a/test/Polly.Core.Tests/Utils/Pipeline/CompositePipelineComponentTests.cs
+++ b/test/Polly.Core.Tests/Utils/Pipeline/CompositePipelineComponentTests.cs
@@ -50,7 +50,7 @@ public async Task Create_EnsureExceptionsNotWrapped()
 
         var pipeline = CreateSut(components);
         await pipeline
-            .Invoking(p => p.ExecuteCore((_, _) => Outcome.FromResultAsTask(10), ResilienceContextPool.Shared.Get(), "state").AsTask())
+            .Invoking(p => p.ExecuteCore((_, _) => Outcome.FromResultAsValueTask(10), ResilienceContextPool.Shared.Get(), "state").AsTask())
             .Should()
             .ThrowAsync<NotSupportedException>();
     }
@@ -90,7 +90,7 @@ public async Task Create_Cancelled_EnsureNoExecution()
         var context = ResilienceContextPool.Shared.Get();
         context.CancellationToken = cancellation.Token;
 
-        var result = await pipeline.ExecuteOutcomeAsync((_, _) => Outcome.FromResultAsTask("result"), context, "state");
+        var result = await pipeline.ExecuteOutcomeAsync((_, _) => Outcome.FromResultAsValueTask("result"), context, "state");
         result.Exception.Should().BeOfType<OperationCanceledException>();
     }
 
@@ -108,7 +108,7 @@ public async Task Create_CancelledLater_EnsureNoExecution()
         var context = ResilienceContextPool.Shared.Get();
         context.CancellationToken = cancellation.Token;
 
-        var result = await pipeline.ExecuteOutcomeAsync((_, _) => Outcome.FromResultAsTask("result"), context, "state");
+        var result = await pipeline.ExecuteOutcomeAsync((_, _) => Outcome.FromResultAsValueTask("result"), context, "state");
         result.Exception.Should().BeOfType<OperationCanceledException>();
         executed.Should().BeTrue();
     }
diff --git a/test/Polly.Extensions.Tests/Issues/IssuesTests.OnCircuitBreakWithServiceProvider_796.cs b/test/Polly.Extensions.Tests/Issues/IssuesTests.OnCircuitBreakWithServiceProvider_796.cs
index cf35ede2586..13cae165f7d 100644
--- a/test/Polly.Extensions.Tests/Issues/IssuesTests.OnCircuitBreakWithServiceProvider_796.cs
+++ b/test/Polly.Extensions.Tests/Issues/IssuesTests.OnCircuitBreakWithServiceProvider_796.cs
@@ -33,8 +33,8 @@ public async Task OnCircuitBreakWithServiceProvider_796()
                     },
                     ShouldHandle = args => args.Outcome.Result switch
                     {
-                        string result when result == "error" => PredicateResult.True,
-                        _ => PredicateResult.False
+                        string result when result == "error" => PredicateResult.True(),
+                        _ => PredicateResult.False()
                     }
                 });
         });
diff --git a/test/Polly.Extensions.Tests/Issues/IssuesTests.OverrideLibraryStrategies_1072.cs b/test/Polly.Extensions.Tests/Issues/IssuesTests.OverrideLibraryStrategies_1072.cs
index ccf216f19cc..cce6d52d275 100644
--- a/test/Polly.Extensions.Tests/Issues/IssuesTests.OverrideLibraryStrategies_1072.cs
+++ b/test/Polly.Extensions.Tests/Issues/IssuesTests.OverrideLibraryStrategies_1072.cs
@@ -23,9 +23,9 @@ public void OverrideLibraryStrategies_898(bool overrideStrategy)
             {
                 ShouldHandle = args => args.Outcome.Exception switch
                 {
-                    InvalidOperationException => PredicateResult.True,
-                    SocketException => PredicateResult.True,
-                    _ => PredicateResult.False
+                    InvalidOperationException => PredicateResult.True(),
+                    SocketException => PredicateResult.True(),
+                    _ => PredicateResult.False()
                 },
                 Delay = TimeSpan.Zero
             }));
@@ -68,8 +68,8 @@ private static void AddLibraryServices(IServiceCollection services)
         {
             ShouldHandle = args => args.Outcome.Exception switch
             {
-                InvalidOperationException => PredicateResult.True,
-                _ => PredicateResult.False
+                InvalidOperationException => PredicateResult.True(),
+                _ => PredicateResult.False()
             }
         }));
     }
diff --git a/test/Polly.RateLimiting.Tests/RateLimiterResilienceStrategyTests.cs b/test/Polly.RateLimiting.Tests/RateLimiterResilienceStrategyTests.cs
index e8380d1569e..7972e490734 100644
--- a/test/Polly.RateLimiting.Tests/RateLimiterResilienceStrategyTests.cs
+++ b/test/Polly.RateLimiting.Tests/RateLimiterResilienceStrategyTests.cs
@@ -70,7 +70,7 @@ public async Task Execute_LeaseRejected(bool hasEvents, bool hasRetryAfter)
 
         var strategy = Create();
         var context = ResilienceContextPool.Shared.Get(cts.Token);
-        var outcome = await strategy.ExecuteOutcomeAsync((_, _) => Outcome.FromResultAsTask("dummy"), context, "state");
+        var outcome = await strategy.ExecuteOutcomeAsync((_, _) => Outcome.FromResultAsValueTask("dummy"), context, "state");
 
         outcome.Exception
             .Should()
diff --git a/test/Polly.Specs/ResiliencePipelineConversionExtensionsTests.cs b/test/Polly.Specs/ResiliencePipelineConversionExtensionsTests.cs
index eb5fe71be9e..f213e1f614c 100644
--- a/test/Polly.Specs/ResiliencePipelineConversionExtensionsTests.cs
+++ b/test/Polly.Specs/ResiliencePipelineConversionExtensionsTests.cs
@@ -152,7 +152,7 @@ public void RetryStrategy_AsSyncPolicy_Ok()
         var policy = new ResiliencePipelineBuilder<string>()
             .AddRetry(new RetryStrategyOptions<string>
             {
-                ShouldHandle = _ => PredicateResult.True,
+                ShouldHandle = _ => PredicateResult.True(),
                 BackoffType = DelayBackoffType.Constant,
                 MaxRetryAttempts = 5,
                 Delay = TimeSpan.FromMilliseconds(1)
diff --git a/test/Polly.Testing.Tests/ResiliencePipelineExtensionsTests.cs b/test/Polly.Testing.Tests/ResiliencePipelineExtensionsTests.cs
index 2018ba08824..291329679b4 100644
--- a/test/Polly.Testing.Tests/ResiliencePipelineExtensionsTests.cs
+++ b/test/Polly.Testing.Tests/ResiliencePipelineExtensionsTests.cs
@@ -18,7 +18,7 @@ public void GetPipelineDescriptor_Generic_Ok()
         var strategy = new ResiliencePipelineBuilder<string>()
             .AddFallback(new()
             {
-                FallbackAction = _ => Outcome.FromResultAsTask("dummy"),
+                FallbackAction = _ => Outcome.FromResultAsValueTask("dummy"),
             })
             .AddRetry(new())
             .AddCircuitBreaker(new())