Async.Await not catching Task exception

痴心易碎 提交于 2019-11-29 19:05:13

问题


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?


回答1:


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



回答2:


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
        )


来源:https://stackoverflow.com/questions/25166363/async-await-not-catching-task-exception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!