2015-03-17 5 views
9

सी # ReceiveActor में मैं सिर्फ कक्षा में निजी क्षेत्र के रूप में राज्य कर सकता हूं। एफ # एपीआई के साथ एक बेवकूफ तरीके से मैं इसे कैसे करना चाहिए?एफ # Akka.NET अभिनेता में राज्य कैसे स्टोर करें?

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

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

आप नहीं हैं कि क्या कर रहे हैं खोज रहे हैं, लेकिन [एफ # एजेंटों के लिए, बेवकूफ दृष्टिकोण राज्य को ले जाने के लिए एक रिकर्सिव लूप का उपयोग करना है] (https://msdn.microsoft.com/en-us/library/ee370357.aspx)। हालांकि, अगर Akka.NET आपको उत्परिवर्तन उन्मुख मार्ग से नीचे ले जाता है, तो यह 'अच्छी तरह से' करना असंभव साबित हो सकता है। क्या आप 'प्राप्तकर्ता' से प्राप्त करने के अलावा अन्य तरीकों से Akka.NET के लिए एक अभिनेता को कार्यान्वित कर सकते हैं? कुछ ऐसा जो आपको रिकर्सिव पोल लूप का उपयोग करने में सक्षम बनाता है? –

+1

बीटीडब्ल्यू, अगर कोई और मूर्खतापूर्ण समाधान है, तो मैं इसके बारे में सिर्फ अनजान हूं, और साथ ही शिक्षित होना चाहता हूं :) –

उत्तर

18

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

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

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 एफ # एपीआई पर पूर्ण प्रलेखन के लिए है http://getakka.net/wiki/FSharp%20API

7

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

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

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 
संबंधित मुद्दे