首页 > 解决方案 > Haskell中的计时器(Control.Concurrent.Timer):重复执行

问题描述

试图找出处理 Haskell 中重复操作的最佳实践,使用Control.Concurrent.Timer. 找不到好的例子。

假设我重复了必须在应用程序中完成的操作。假设它正在从某个网页获取数据。

import Control.Concurrent.Suspend.Lifted 
import Control.Concurrent.Timer

main :: IO ()
main = do
  url <- fetchUrl :: IO Url
  doSomethingWithUrl url

我希望在 main 中重复获取 url,以便数据始终是最新的。怎么可能做到?

标签: haskelltimer

解决方案


您的需求听起来适合 IORef 或 MVar。键入且未测试的代码是:

import Data.IORef (readIORef, writeIORef, newIORef)
import Control.Concurrent (threadDelay,forkIO)
import Control.Monad (void)

main :: IO ()
main = do
  ref <- newIORef mempty {- or default value -}
  _ <- forkIO (updatePeriodically fetchUrl ref)
  scotty $ do
        liftIO (readIORef ref) >>= etcEtc

updatePeriodically :: (IO SomeType) -> IORef SomeType -> IO ()
updatePeriodically op ref =
    let update = op >>= writeIORef ref
    forever $ threadDelay periodInMicroSeconds >> void (forkIO update)

这并不完美,如果其中一个fetchUrl调用被严重延迟,那么它的写入可能会破坏一个快速返回的新调用。这可能是一个小问题,但您可以使用计数器以及比较和交换操作来处理它。


推荐阅读