Skip to content

Commit

Permalink
add another test for #3254 (#3367)
Browse files Browse the repository at this point in the history
* add another test for #3254, ported from paket. related to #3350 and fsprojects/Paket#2553

* Fix exception message
  • Loading branch information
matthid authored and dsyme committed Jul 25, 2017
1 parent f6049d5 commit 4559cfd
Showing 1 changed file with 54 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,60 @@ type CancellationType() =
yield async { do linkedCts.Dispose() }
}
asyncs |> Async.Parallel |> Async.RunSynchronously |> ignore


[<Test>]
member this.AwaitTaskCancellationAfterAsyncTokenCancellation() =
let StartCatchCancellation cancellationToken (work) =
Async.FromContinuations(fun (cont, econt, _) ->
// When the child is cancelled, report OperationCancelled
// as an ordinary exception to "error continuation" rather
// than using "cancellation continuation"
let ccont e = econt e
// Start the workflow using a provided cancellation token
Async.StartWithContinuations( work, cont, econt, ccont,
?cancellationToken=cancellationToken) )

/// Like StartAsTask but gives the computation time to so some regular cancellation work
let StartAsTaskProperCancel taskCreationOptions cancellationToken (computation : Async<_>) : System.Threading.Tasks.Task<_> =
let token = defaultArg cancellationToken Async.DefaultCancellationToken
let taskCreationOptions = defaultArg taskCreationOptions System.Threading.Tasks.TaskCreationOptions.None
let tcs = new System.Threading.Tasks.TaskCompletionSource<_>("StartAsTaskProperCancel", taskCreationOptions)

let a =
async {
try
// To ensure we don't cancel this very async (which is required to properly forward the error condition)
let! result = StartCatchCancellation (Some token) computation
do
tcs.SetResult(result)
with exn ->
tcs.SetException(exn)
}
Async.Start(a)
tcs.Task

let cts = new CancellationTokenSource()
let tcs = System.Threading.Tasks.TaskCompletionSource<_>()
let t =
async {
do! tcs.Task |> Async.AwaitTask
}
|> StartAsTaskProperCancel None (Some cts.Token)

// First cancel the token, then set the task as cancelled.
async {
do! Async.Sleep 100
cts.Cancel()
do! Async.Sleep 100
tcs.TrySetException (TimeoutException "Task timed out after token.")
|> ignore
} |> Async.Start

try
let res = t.Wait(1000)
Assert.Fail (sprintf "Excepted TimeoutException wrapped in an AggregateException, but got %A" res)
with :? AggregateException as agg -> ()

[<Test>]
member this.Equality() =
let cts1 = new CancellationTokenSource()
Expand Down

0 comments on commit 4559cfd

Please sign in to comment.