问题描述
我正在使用异步库,并尝试在实践中弄清其API。我注意到我没有想到的奇怪行为。它看起来像个错误,但也许是一个功能,我只需要知道一种解决方法。
import Control.Concurrent
import Control.Concurrent.Async
> withAsync (putStrLn "HELLO") (\_ -> putStrLn "WORLD")
WORLHEDL
上面的代码片段工作得很好-两条线都执行了,但是更复杂的异步主体被部分评估了。
> withAsync (putStrLn "XXXXXXXXXX" >> putStrLn "HELLO") (\_ -> putStrLn "WORLD")
WOXRXLXDX
请参阅,第二个putStrLn不执行。 我想我需要将整个异步主体包装在某种形式的bnf中,但无论如何看起来还是很奇怪的。为什么withAsync不帮我呢?
forkIO正常工作,但是我不想为松懈而烦恼。 异步具有对库unlift-async,可自动传播monad。
forkIO (Prelude.putStrLn "XXXXXXXXXX" >> Prelude.putStrLn "HELLO")
ThreadXIXdX X1X1X3X
XXX
HELLO
我发现带有叉功能的可升降式底座。它可以作为forkIO并将父monad传递给子线程。
解决方法
withAsync
在主线程(第二个参数)终止时中断派生线程(第一个参数)。这在documentation of withAsync
中是明确的:
函数返回或引发异常时,将在
uninterruptibleCancel
上调用Async
。(...)这是
async
的有用变体,可确保不会Async
意外运行。
如果只想派生线程,请使用async
。
async (putStrLn "XXXXXXXX" >> putStrLn "WORLD") >> putStrLn "HELLO"