Skip to content

Commit 7285499

Browse files
committed
Fix ValueTask.tryWith
1 parent 28a8d5a commit 7285499

File tree

1 file changed

+27
-18
lines changed

1 file changed

+27
-18
lines changed

src/FSharpPlus/Extensions/ValueTask.fs

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -282,24 +282,33 @@ module ValueTask =
282282
let unwrapException (agg: AggregateException) =
283283
if agg.InnerExceptions.Count = 1 then agg.InnerExceptions.[0]
284284
else agg :> Exception
285-
try
286-
let task = body ()
287-
if task.IsCompleted then
288-
match task with
289-
| Succeeded _ -> task
290-
| Faulted exn -> compensation (unwrapException exn)
291-
| Canceled -> compensation (TaskCanceledException ())
292-
else
293-
let tcs = TaskCompletionSource<'T> ()
294-
let f = function
295-
| Succeeded r -> tcs.SetResult r
296-
| Faulted exn -> continueTask tcs (compensation (unwrapException exn)) (fun r -> try tcs.SetResult r with e -> tcs.SetException e)
297-
| Canceled -> continueTask tcs (compensation (TaskCanceledException ())) (fun r -> try tcs.SetResult r with e -> tcs.SetException e)
298-
task.ConfigureAwait(false).GetAwaiter().UnsafeOnCompleted (fun () -> f task)
299-
ValueTask<'T> tcs.Task
300-
with
301-
| :? AggregateException as exn -> compensation (unwrapException exn)
302-
| exn -> compensation exn
285+
286+
let mutable ran = false
287+
288+
let compensation exn =
289+
if not ran then ran <- true
290+
try compensation exn
291+
with e -> raise e
292+
293+
let task =
294+
try body ()
295+
with
296+
| :? AggregateException as aex -> compensation (unwrapException aex)
297+
| exn -> compensation exn
298+
if ran then task
299+
elif task.IsCompleted then
300+
match task with
301+
| Succeeded _ -> task
302+
| Faulted aex -> compensation (unwrapException aex)
303+
| Canceled -> compensation (TaskCanceledException ())
304+
else
305+
let tcs = TaskCompletionSource<'T> ()
306+
let f = function
307+
| Succeeded r -> tcs.SetResult r
308+
| Faulted aex -> continueTask tcs (compensation (unwrapException aex)) (fun r -> try tcs.SetResult r with e -> tcs.SetException e)
309+
| Canceled -> continueTask tcs (compensation (TaskCanceledException ())) (fun r -> try tcs.SetResult r with e -> tcs.SetException e)
310+
task.ConfigureAwait(false).GetAwaiter().UnsafeOnCompleted (fun () -> f task)
311+
ValueTask<'T> tcs.Task
303312

304313
/// Used to de-sugar try .. finally .. blocks in Computation Expressions.
305314
let inline tryFinally ([<InlineIfLambda>]compensation : unit -> unit) ([<InlineIfLambda>]body: unit -> ValueTask<'T>) : ValueTask<'T> =

0 commit comments

Comments
 (0)