F#子代理。有这个'这个'指针

时间:2015-03-20 12:25:50

标签: f# actor

我有以下模式 - 我想知道解决它的最佳方法是什么。代理#1想要发出代理#2并向自己提供回叫。代理#1是否有某种“this”指针可以提供给子代理#2?

解决此问题的一种方法是使用一些代理注册表,并让父母将其“id”提供给孩子。我想知道是否有更直接的方式。我在下面发布了一段代码片段

type Agent<'a> = MailboxProcessor<'a>

type A1Message =
    | CreateChild
    | ChildNotification

type A2Message =
    | Start
    | Stop

let a1Ref = ref <| Unchecked.defaultof<Agent<A1Message>>

let a1 =
    Agent<A1Message>.Start(
        fun inbox ->
            async {      
                let a2 = ref <| Unchecked.defaultof<Agent<A2Message>>                      
                while true do
                        let! msg = inbox.Receive()
                        match msg with
                        | CreateChild -> 
                            a2 := Agent<A2Message>.Start(
                                        fun inbox ->
                                            async {
                                                while true do
                                                    let! msg = inbox.Receive()
                                                    match msg with
                                                    | Start -> 
                                                        (!a1Ref).Post ChildNotification
                                                    | Stop -> ()
                                            }
                                        )
                            (!a2).Post Start
                        | ChildNotification -> 
                            printfn "Notified by Child"
                            (!a2).Post Stop
            }
        )

do
    a1Ref := a1

1 个答案:

答案 0 :(得分:2)

有些人可能认为this指针不是FP惯用语,并且FP有更好的模式。

如果a2处理器需要以一种方式发布到a1处理器,那么可能就是这样 像这样:

例如

type A1Message =
    | CreateChild
    | ChildNotification of MailboxProcessor<A2Message>

and A2Message =
    | Start
    | Stop

let a1 (inbox : MailboxProcessor<_>) =
    async {      
        printfn "Parent started"
        while true do
                let! msg = inbox.Receive()
                printfn "Parent received: %A" msg
                match msg with
                | CreateChild -> 
                    let childInbox = MailboxProcessor.Start (a2 inbox)
                    childInbox.Post Start
                | ChildNotification childInbox -> 
                    childInbox.Post Stop
    }

let a2 (parentInbox : MailboxProcessor<_>) (inbox : MailboxProcessor<_>) = 
    async {
        printfn "Child started"
        let cont = ref true
        while !cont do
            let! msg = inbox.Receive()
            printfn "Child received: %A" msg
            match msg with
            | Start -> parentInbox.Post <| ChildNotification inbox
            | Stop  ->
                cont := false
        printfn "Child stopped"
    }

open System

[<EntryPoint>]
let main argv = 

    printfn "Starting parent"
    let inbox = MailboxProcessor.Start a1

    inbox.Post CreateChild

    ignore <| Console.ReadKey ()

    0
  1. 创建a2处理器时,a1处理器将其收件箱传递给a2处理器,使a2处理器可以轻松发布到a1处理器。
  2. 修改ChildNotification消息以携带子处理器的收件箱,使a1进程可以轻松地发布给孩子。
  3. 希望这对你有帮助