9

I have a Task that does not return anything. You can't do an Async.AwaitTask on such a Task, so you need to do an Async.AwaitIAsyncTask instead. Unfortunately this seems to just swallow any exceptions that the underlying Task throws out: -

TaskFactory().StartNew(Action(fun _ -> failwith "oops"))
|> Async.AwaitIAsyncResult
|> Async.Ignore
|> Async.RunSynchronously

// val it : unit = ()

On the other hand, AwaitTask correctly cascades the exception: -

TaskFactory().StartNew(fun _ -> failwith "oops"                               
                                5)
|> Async.AwaitTask
|> Async.Ignore
|> Async.RunSynchronously

// POP!

What's the best way of treating regular (non-generic) Tasks as Async yet still get propagation of exceptions?

2 Answers 2

9

As an option that will properly handle cancellation:

open System.Threading.Tasks

module Async =
    let AwaitTask (t: Task) = 
        Async.FromContinuations(fun (s, e, c) ->
            t.ContinueWith(fun t -> 
                if t.IsCompleted then s()
                elif t.IsFaulted then e(t.Exception)
                else c(System.OperationCanceledException())
                )
            |> ignore
        )
Sign up to request clarification or add additional context in comments.

1 Comment

slight correction, the IsCompleted check must be made after the IsFaulted check because a fault is also considered completed.
2

From the Xamarin F# Shirt App (which I originally borrowed from Dave Thomas):

[<AutoOpen>]
module Async =
     let inline awaitPlainTask (task: Task) = 
        // rethrow exception from preceding task if it faulted
        let continuation (t : Task) = if t.IsFaulted then raise t.Exception
        task.ContinueWith continuation |> Async.AwaitTask

4 Comments

Just let continuation (t : Task) = if t.IsFaulted then raise t.Exception is probably clearer.
@Daniel Feel free to make it better. :-) I'm not possessive of my answers!
Think I first saw this here: theburningmonk.com/2012/10/…
downsides: cancellation is not handled properly, reraising exception drops the stacktrace

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.