Exception handling Async.Wait未捕获任务异常

Exception handling Async.Wait未捕获任务异常,exception-handling,f#,task-parallel-library,f#-async,Exception Handling,F#,Task Parallel Library,F# Async,我有一个不返回任何内容的任务。您无法对此类任务执行Async.AwaitiAsk,因此需要改为执行Async.AwaitIAsyncTask。不幸的是,这似乎吞没了底层任务抛出的任何异常:- TaskFactory().StartNew(Action(fun _ -> failwith "oops")) |> Async.AwaitIAsyncResult |> Async.Ignore |> Async.RunSynchronously // val it : uni

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

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

// val it : unit = ()
另一方面,WaitTask正确级联异常:-

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

// POP!
将常规(非泛型)任务视为异步任务但仍会传播异常的最佳方法是什么?

来自(我最初从Dave Thomas那里借用的):

[]
模块异步=
让内联任务(任务:任务)=
//如果前一个任务出现故障,则从中重试异常
let continuation(t:Task)=如果t.IsFaulted,则引发t.Exception
task.ContinueWith continuation |>Async.waittask

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

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
        )

只需
让continuation(t:Task)=如果t.IsFaulted,则引发t.Exception
可能更清晰。@Daniel请随意改进。:-)我对我的答案没有占有欲!我想我首先在这里看到了这一点:缺点:取消处理不正确,重新启动异常会导致stacktraceslight更正失败,IsCompleted检查必须在IsFaulted检查之后进行,因为故障也被视为已完成。
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
        )