[英]Why does Async.Start seemingly propagate uncatchable exceptions?
考慮這個控制台應用:
let throwAsync =
async { failwith "" }
[<EntryPoint>]
let main argv =
try Async.Start throwAsync
with _ -> printfn "Failed"
System.Console.Read() |> ignore
0
應用程序在運行時立即崩潰。 這對我來說沒有意義,原因有兩個:
Async.Start
冒泡(渲染try ... with
沒有意義,但是它存在於第2點) try ... with
包圍,但異常未被捕獲(它永遠不會打印"Failed"
,同樣,應用程序崩潰)。 這是怎么回事?
異步塊執行的線程池線程拋出異常。
所以,是的,這意味着異常不會傳播到運行Async.Start
的線程,並且永遠不會命中try-with
塊。 而且,這意味着異常現在被拋到其他地方,並且沒有任何異常處理它將使您的應用程序崩潰。
引用MSDN :
線程池線程中未處理的異常終止進程。 此規則有三個例外:
- 由於調用了
Thread.Abort
因此在線程池線程中拋出System.Threading.ThreadAbortException
。- 由於正在卸載應用程序域,因此在線程池線程中拋出
System.AppDomainUnloadedException
。- 公共語言運行庫或主機進程終止該線程。
有關更多信息,請參閱托管線程中的例外 。
使用Async.Start
執行時, try
無法在async
捕獲異常,因為它們分叉在不同的線程中。 如果要捕獲它,可以使用Async.RunSynchronously
或在另一個async
:
let throwAsync = async { failwith "I was not caught!" }
let catchAsync = async {
try
do! throwAsync
with _-> printfn "caught inside async!"
}
[<EntryPoint>]
let main argv =
try throwAsync |> Async.RunSynchronously
with _ -> printfn "caught outside!"
try catchAsync |> Async.Start
with _ -> printfn "I did not catch it either!"
System.Console.Read() |> ignore
printfn "finishing!"
0
輸出:
caught outside!
caught inside async!
finishing!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.