如何在异步中强制执行完整评估?
How to enforce full evaluation inside async?
我正在玩异步库,并试图在实践中找出它的 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 工作得很好,但我不想费心去解除。
async 有一对库 unlift-async 自动传播 monad。
forkIO (Prelude.putStrLn "XXXXXXXXXX" >> Prelude.putStrLn "HELLO")
ThreadXIXdX X1X1X3X
XXX
HELLO
我找到了带分叉功能的 lifted-base。它用作 forkIO 并将父 monad 传递给子线程。
withAsync
在主线程(第二个参数)终止时中断分叉线程(第一个参数)。这在 documentation of withAsync
:
中是明确的
When the function returns or throws an exception, uninterruptibleCancel
is called on the Async
.
(...) This is a useful variant of async
that ensures an Async
is never left running unintentionally.
如果你只想分叉一个线程,使用async
。
async (putStrLn "XXXXXXXX" >> putStrLn "WORLD") >> putStrLn "HELLO"
我正在玩异步库,并试图在实践中找出它的 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 工作得很好,但我不想费心去解除。 async 有一对库 unlift-async 自动传播 monad。
forkIO (Prelude.putStrLn "XXXXXXXXXX" >> Prelude.putStrLn "HELLO")
ThreadXIXdX X1X1X3X
XXX
HELLO
我找到了带分叉功能的 lifted-base。它用作 forkIO 并将父 monad 传递给子线程。
withAsync
在主线程(第二个参数)终止时中断分叉线程(第一个参数)。这在 documentation of withAsync
:
When the function returns or throws an exception,
uninterruptibleCancel
is called on theAsync
.(...) This is a useful variant of
async
that ensures anAsync
is never left running unintentionally.
如果你只想分叉一个线程,使用async
。
async (putStrLn "XXXXXXXX" >> putStrLn "WORLD") >> putStrLn "HELLO"