-
Notifications
You must be signed in to change notification settings - Fork 22
Open
Description
I propose including AwaitTaskCorrect (maybe with another name)
open System
open System.Threading.Tasks
type Async with
static member AwaitTaskCorrect(task : Task) : Async<unit> =
Async.FromContinuations(fun (sc,ec,cc) ->
task.ContinueWith(fun (task:Task) ->
if task.IsFaulted then
let e = task.Exception
if e.InnerExceptions.Count = 1 then ec e.InnerExceptions.[0]
else ec e
elif task.IsCanceled then
ec(TaskCanceledException())
else
sc ())
|> ignore)
static member AwaitTaskCorrect(task : Task<'T>) : Async<'T> =
Async.FromContinuations(fun (sc,ec,cc) ->
task.ContinueWith(fun (task:Task<'T>) ->
if task.IsFaulted then
let e = task.Exception
if e.InnerExceptions.Count = 1 then ec e.InnerExceptions.[0]
else ec e
elif task.IsCanceled then
ec(TaskCanceledException())
else
sc task.Result)
|> ignore)
// examples
let mkFailingTask exn = Task.Factory.StartNew<_>(fun () -> raise exn)
let test1 taskAwaiter =
async {
try
return! taskAwaiter (mkFailingTask (ArgumentException()))
with
| :? ArgumentException -> return true
| :? AggregateException -> return false
} |> Async.RunSynchronously
test1 Async.AwaitTask // false
test1 Async.AwaitTaskCorrect // true
let test2 taskAwaiter =
async {
try
return! taskAwaiter (mkFailingTask (AggregateException("kaboom!")))
with
| :? AggregateException as e when e.Message = "kaboom!" -> return true
| :? AggregateException -> return false
} |> Async.RunSynchronously
test2 Async.AwaitTask // false
test2 Async.AwaitTaskCorrect // true
The existing way of approaching this problem in F# is copying the snippet in your project, ref : jet/equinox#198
Pros and Cons
The advantages of making this adjustment to F#:
- Provides a better implementation of Async.AwaitTask where the actual exception of a failing task is passed to the async mechanism.
- Works as C# would handle taks
The disadvantages of making this adjustment to F# are:
- Might be confusing having 2 AwaitTask
- If AwaitTask is "fixed" then is a breaking change
Extra information
Estimated cost (XS, S, M, L, XL, XXL): No idea
Related suggestions: at this moment I don't know of any other related suggestions might edit in the future
Affidavit (please submit!)
Please tick this by placing a cross in the box:
- This is not a question (e.g. like one you might ask on stackoverflow) and I have searched stackoverflow for discussions of this issue
- I have searched both open and closed suggestions on this site and believe this is not a duplicate
- This is not something which has obviously "already been decided" in previous versions of F#. If you're questioning a fundamental design decision that has obviously already been taken (e.g. "Make F# untyped") then please don't submit it.
Please tick all that apply:
- This is not a breaking change to the F# language design
- I or my company would be willing to help implement and/or test this
bartelink, jdodds, dominikus1993, thomaswolff, Programmerino and 4 more