提问人:hololeap 提问时间:5/29/2018 最后编辑:AJFhololeap 更新时间:5/30/2018 访问量:239
如何使用 safe-exceptions 库捕获异步异常?
How to catch async exceptions with the safe-exceptions library?
问:
我正在尝试使用 Haskell 构建并发且健壮的代码,建议我使用 safe-exceptions 和 async 库。但是,我很难理解如何处理操作中抛出的非致命错误。async
例如,如果有一个简单的循环每 n 秒检查一次网络资源,那么使用会导致在单独线程中抛出异常的函数来阻止此循环是有意义的。当然,也有可能由于网络故障或其他问题而从线程内部抛出 an。根据异常的类型及其包含的数据,我想控制单独的线程是忽略异常、执行某些操作、停止还是在主线程中引发异常。cancel
AsyncCancelled
IOError
使用 safe-exceptions 库,唯一能够执行此操作的函数是其他类似的函数,它们在文档中被标记为危险。除此之外,异步库中还有,但是当我尝试提取一个 :catchAsync
waitCatch
fromException
Nothing
IOError
{-# LANGUAGE ScopedTypeVariables #-}
import Control.Concurrent.Async
import Control.Concurrent hiding (throwTo)
import Control.Exception.Safe
import Control.Monad
import System.IO
import System.IO.Error hiding (catchIOError)
main = do
hSetBuffering stdin NoBuffering
putStrLn "Press any key to continue..."
a <- async runLoop
async $ hWaitForInput stdin (-1) *>
throwTo (asyncThreadId a) (userError "error")
waitCatch a >>= either handler nothing
where
printThenWait i = putStr (show i ++ " ") *> threadDelay 1000000
runLoop = sequence_ $ printThenWait <$> [1..]
nothing _ = pure ()
handler e
| Just (e' :: IOError) <- fromException e =
putStrLn "It's an IOError!"
| (Nothing :: Maybe IOError) <- fromException e =
putStrLn "We got Nothing!"
我对从异步异常中恢复的危险有点困惑,尤其是当标准函数(例如导致它们被抛出)时,我不知道使用这两个库时处理它们的推荐方法是什么。这是一个推荐的实例,还是有另一种方法可以处理我没有发现的这些类型的情况?cancel
catchAsync
答:
请注意,将同步异常包装到 中,并且是同步的。(我不知道为什么这种包装是必要的,无论如何你永远不应该异步抛出同步异常。Control.Exception.Safe.throwTo
AsyncExceptionWrapper
IOError
要使您的代码正常工作,您应该捕获或使用 .但实际上我不明白你想做什么,很可能你把事情搞得太复杂了。AsyncExceptionWrapper
Control.Exception.throwTo
评论