我有一个解决了一些问题的程序,我决定在一个漂亮的GUI中监视它的作用。对于GUI,我选择Gtk
,这意味着我需要在专用线程中运行mainGUI
循环,我的程序的其余部分将占用不同的线程。我认为我的程序和其他线程之间的通信将使用Chan
向一个方向流动。我进一步决定使用FRP来更新来自worker的通知的GUI(原始程序在其单独的线程中的逻辑)。所以我尝试编写一个简单的线程示例,其中一个线程将IO
个动作发送到执行操作的监视线程(显示它们)。这是我的尝试:
import Control.Concurrent
import Control.Monad
import Reactive.Banana
import Reactive.Banana.Frameworks
main = do
c <- newChan
forkIO $ do
actuate <=< compile $ reactimate'
<=< changes
<=< fromPoll
$ readChan c
forever $ do
threadDelay 3000000
putStrLn "sending msg"
writeChan c $ putStrLn "receiving msg"
这显然不起作用(它只打印sending msg
)否则我不会在这里。我究竟做错了什么?我需要一个与投票相同的不同事件吗?怎么做?
我期待一些文本副本的交错:sending msg
和receiving msg
。
澄清我想要离开
main = do
c <- newChan
forkIO . forever . join . readChan $ c
forever $ do
threadDelay 3000000
putStrLn "sending msg"
writeChan c $ putStrLn "receiving msg"
其中c :: Chan (IO ())
中的每个消息都在线程中明确地读取(可能是阻塞),消息的反应性处理,即描述与GUI元素互连的事件/行为的网络,然后让线程执行GUI循环。网络需要处理通道中的轮询值和触发事件。
我正在寻找的解决方案(或类似的东西):
main = do
(msgHandler, msgFire) <- newAddHandler
forkIO $ do
actuate <=< compile $ do
eMsg <- fromAddHandler msgHandler
reactimate $ putStrLn <$> eMsg
forever $ do
threadDelay 3000000
putStrLn "sending msg"
msgFire "receiving msg"
答案 0 :(得分:2)
Value
州的文档
只要事件网络处理输入事件,结果行为就会更新。
由于没有事件,因此永远不会更新。 observeSingleEventOfType
旨在作为一种快速而肮脏的方式来读取可变数据,但不是为了更新网络。相反,文档建议我们使用fromPoll
。但是,既然我们或者因为我们想要fromPoll
,那么让我们使用newEvent
,这似乎非常合适:它允许我们创建一个fromChanges
,我们通过调用{{1}来添加值}(这是Event
的别名)。
Event