Async.Await没有捕获任务异常

Isa*_*ham 9 f# exception-handling task-parallel-library f#-async

我有一个不返回任何东西的任务.你不能在这样的Task上做Async.AwaitTask,所以你需要做一个Async.AwaitIAsyncTask.不幸的是,这似乎只是吞下了底层任务抛出的任何异常: -

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

// val it : unit = ()
Run Code Online (Sandbox Code Playgroud)

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

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

// POP!
Run Code Online (Sandbox Code Playgroud)

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

des*_*sco 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
        )
Run Code Online (Sandbox Code Playgroud)


N_A*_*N_A 2

来自Xamarin F# Shirt 应用程序(我最初从 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
Run Code Online (Sandbox Code Playgroud)

  • 缺点:取消处理不正确,重新引发异常会丢弃堆栈跟踪 (2认同)