Tôi đang triển khai REPL cho một trình thông dịch Đề án trong Haskell và tôi muốn xử lý một số sự kiện không đồng bộ như UserInterrupt, StackOverflow, HeapOverflow, v.v ... Về cơ bản, tôi muốn dừng tính toán hiện nay khi UserInterrupt xảy ra và in một thông điệp phù hợp khi StackOverflow và HeapOverflow xảy ra, vv tôi thực hiện điều này như sau:Xử lý ngoại lệ UserInterrupt trong Haskell
repl evaluator = forever $ (do
putStr ">>> " >> hFlush stdout
out <- getLine >>= evaluator
if null out
then return()
else putStrLn out)
`catch`
onUserInterrupt
onUserInterrupt UserInterrupt = putStrLn "\nUserInterruption"
onUserInterrupt e = throw e
main = do
interpreter <- getMyLispInterpreter
handle onAbort (repl $ interpreter "stdin")
putStrLn "Exiting..."
onAbort e = do
let x = show (e :: SomeException)
putStrLn $ "\nAborted: " ++ x
Nó hoạt động như mong đợi với một ngoại lệ. Nếu tôi bắt đầu phiên dịch và nhấn Ctrl-Z + Enter, tôi nhận được:
>>> ^Z
Aborted: <stdin>: hGetLine: end of file
Exiting...
Đúng vậy. Nhưng nếu tôi bắt đầu phiên dịch và nhấn Ctrl-C, tiếp theo là Ctrl-Z + Enter, tôi nhận được:
>>>
UserInterruption
>>> ^Z
Và nó bị treo và tôi không thể sử dụng thông dịch viên nữa. Tuy nhiên, nếu tôi nhấn lại Ctrl-C, thì REPL sẽ mở khóa. Tôi đã tìm kiếm rất nhiều và tôi không thể tìm ra nguyên nhân của nó. Bất cứ ai có thể giải thích cho tôi?
Rất cám ơn! xử lý
Tôi chưa bao giờ thấy Ctrl-Z bị bắt. Ctrl-C đầu tiên được chụp, nhưng cái thứ hai thì không. Đó có lẽ là vấn đề tương tự. Bạn có thể thay đổi mã của mình trong một testcase hoạt động hoàn chỉnh không? F.e. 'return' thay vì 'interpreter' stdin '' và với nhập thích hợp được thêm vào. –