f# - कैसे एक एफ#Akka.NET अभिनेता में राज्य को स्टोर करने के लिए?




actor (2)

सी # ReceiveActor मैं सिर्फ राज्य में निजी क्षेत्र के रूप में राज्य कर सकता हूं। मैं एफ # एपीआई के साथ एक मुहावरेदार तरीके से कैसे कर सकता हूं?

यह एक अच्छा विचार है? कोई विकल्प?

let handleMessage (mailbox: Actor<'a>) msg =
    let mutable i = 1
    match msg with
    | Some x -> i <- i + x
    | None -> ()

जिस तरह से आपने प्रस्तावित किया है वह पूरी तरह से अभिनेता के भीतर राज्य को संचय करने के साधन के रूप में उचित है। किसी भी समय केवल 1 संदेश को संसाधित करने की संगामिति की कमी का मतलब है कि साझा स्मृति स्थान पर विवाद के परिणामस्वरूप अवैध राज्यों में शामिल होना संभव नहीं है।

हालांकि, यह सबसे मुहावरेदार विकल्प नहीं है Akka.Net, एफ # मेलबॉक्स प्रोसेसर के समान अभिनेताओं के साथ काम करने के लिए एफ # एपीआई प्रदान करता है इस मामले में आप अपने अभिनेता को पूंछ पुनर्योजी फ़ंक्शन के रूप में परिभाषित करते हैं जो स्वयं को कुछ नए राज्य के साथ कहते हैं। यहाँ एक उदाहरण है

spawn system "hello" <|
    fun mailbox ->
        let rec loop state =
            actor {
                let! msg = mailbox.Receive ()
                printfn "Received %A. Now received %s messages" msg state
                return! loop (state + 1) //Increment a counter for the number of times the actor has received a message
            }
        loop 0

Akka.Net F # API पर पूर्ण दस्तावेज़ीकरण के लिए http://getakka.net/wiki/FSharp%20API देखें


दो समाधान हैं, उनमें से दोनों स्पष्ट पुनरावर्ती पाश परिभाषा का उपयोग करते हैं, अक्का एफ # कलाकारों की मुख्य अवधारणा

सबसे पहले आप चर को परिभाषित कर सकते हैं, जो केवल अभिनेता के दायरे के भीतर, लूप परिभाषा से पहले दिखाई देनी चाहिए (उदाहरण के नीचे मैंने परिभाषा को संदर्भ कक्ष में बदल दिया है, क्योंकि परिवर्तनशील परिवर्तकों को क्लोजर द्वारा कब्जा नहीं किया जा सकता है):

let actorRef =  
    spawn system "my-actor" <| fun mailbox ->
        let i = ref 1
        let rec loop () =
            actor {
                let! msg = mailbox.Receive()
                match msg with
                | Some x -> i := !i + x
                | None -> ()
                return! loop()
            }
        loop()

हालांकि, अधिक सलाह देने का समाधान संदेश को संभालने के दौरान अपने राज्य को अस्थिर रखने के लिए है , और इसे अगले लूप कॉल में केवल तभी बदलने पर है, जैसे कि:

let actorRef = 
    spawn system "my-actor" <| fun mailbox -> 
        let rec loop i = 
            actor { 
                let! msg = mailbox.Receive()
                match msg with
                | Some x -> return! loop (i + x)
                | None -> return! loop i
            }
        loop 1  // invoke first call with initial state






akka.net