基本的 Hello World

讓我們首先建立一個簡單的 Hello World! MailboxProcessor 處理一種型別的訊息並列印問候語。

你需要訊息型別。它可以是任何東西,但 Discriminated Unions 在這裡是一個自然的選擇,因為它們列出了一個地方的所有可能的情況,你可以在處理時輕鬆使用模式匹配。

// In this example there is only a single case, it could technically be just a string
type GreeterMessage = SayHelloTo of string

現在定義處理器本身。這可以通過 MailboxProcessor<'message>.Start 靜態方法完成,該方法返回一個已準備就緒的已啟動處理器。你也可以使用建構函式,但是你需要確保稍後啟動處理器。

let processor = MailboxProcessor<GreeterMessage>.Start(fun inbox ->
    let rec innerLoop () = async {
        // This way you retrieve message from the mailbox queue
        // or await them in case the queue empty.
        // You can think of the `inbox` parameter as a reference to self.
        let! message = inbox.Receive()
        // Now you can process the retrieved message.
        match message with
        | SayHelloTo name ->
            printfn "Hi, %s! This is mailbox processor's inner loop!" name
        // After that's done, don't forget to recurse so you can process the next messages!
        innerLoop()
    }
    innerLoop ())

Start 的引數是一個引用 MailboxProcessor 本身的函式(當你剛建立它時它還不存在,但是一旦函式執行就可以使用)。這使你可以訪問其各種 ReceiveScan 方法來訪問郵箱中的郵件。在這個函式中,你可以做任何你需要的處理,但通常的方法是一個無限迴圈,它逐個讀取訊息並在每個訊息之後呼叫它們。

現在處理器已準備好,但它沒有任何意義! 為什麼?你需要向其傳送訊息以進行處理。這是通過 Post 方法變體完成的 - 讓我們使用最基本的,即發生的方法。

processor.Post(SayHelloTo "Alice")

這會向 processor 的內部佇列(郵箱)傳送一條訊息,並立即返回,以便呼叫程式碼可以繼續。一旦處理器檢索到訊息,它就會處理它,但是這將以非同步方式釋出它,並且它很可能在一個單獨的執行緒上完成。

很快你就會看到資訊 Hi, Alice! This is mailbox processor's inner loop! 列印到輸出中,你準備好了更復雜的樣本。