Async.Await没有捕获任务异常

时间:2014-08-06 17:19:09

标签: exception-handling f# task-parallel-library f#-async

我有一个不返回任何内容的任务。您无法在此类任务上执行Async.AwaitTask,因此您需要执行Async.AwaitIAsyncTask。不幸的是,这似乎只是吞下了底层任务抛出的任何异常: -

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

// val it : unit = ()

另一方面,AwaitTask正确级联异常: -

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

// POP!

将常规(非通用)任务视为异步但仍然可以传播异常的最佳方法是什么?

2 个答案:

答案 0 :(得分:9)

作为正确处理取消的选项:

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
        )

答案 1 :(得分:2)

来自Xamarin F# Shirt App(我最初借用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