如何在异步内部实施全面评估?

问题描述

我正在使用异步库,并尝试在实践中弄清其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"