Вот программа, которая запускает 1000 асинхронных циклов, настроенных на завершение в течение секунды, и ожидает их всех в течение oop. Скомпилированный с ghc -O2 -threaded
и запущенный с +RTS -N
, он запускается примерно за 1,5 секунды, и ни один из асинхронных устройств не «теряется»:
import Control.Concurrent
import Control.Concurrent.Async
import qualified Data.Set as Set
main :: IO ()
main = do
let n = 1000 :: Int
asyncs0 <- mapM (\i -> async (threadDelay 1000000 >> return i)) [1..n]
let loop :: Set.Set (Async Int) -> IO ()
loop asyncs | null asyncs = return ()
| otherwise = do
(a, _i) <- waitAny (Set.toList asyncs)
loop (Set.delete a asyncs)
loop (Set.fromList asyncs0)
Итак, как упоминалось в комментарии, документация ссылаясь на тот факт, что первый завершенный асин c в предоставленном списке является тем, который будет «возвращен», но если несколько асинхронных завершено, дополнительные не будут «забыты». Вам просто нужно удалить возвращенный асин c из списка и провести повторный опрос, и вы в конечном итоге получите их все.
Таким образом, у вас не должно возникнуть никаких проблем при ожидании нескольких асинхронных операций с * 1008. *.