首页 > 解决方案 > Actor 无法接收发送到`mailbox.Sender()` 的消息?

问题描述

我创建了以下测试代码 - .Net core 2.1 控制台应用程序。它仅打印以下消息

TestActor 从 [akka://MySystem/user/Scheduler#1426101451] 收到消息 MyTask ("Test1","Test1")

但是Ok 0演员无法接收到消息scheduler

open System
open Akka.FSharp
open Akka

type MyTask = MyTask of item1: string * item2: string 

let system = System.create "MySystem" <| Configuration.load ()

let scheduler (actors: Actor.IActorRef) (mailbox: Actor<Result<int, string>>) =
    let rec loop (list: int list list) = actor {
        let! m = mailbox.Receive ()
        let sender = mailbox.Sender ()
        let akkaName = mailbox.Self.Path.Name
        printfn "%s received message %A from %A" akkaName m sender
        return! loop []
    }
    actors <! MyTask("Test1", "Test1")
    loop []

let processor (mailbox: Actor<MyTask>) =
    let rec loop () = actor {
        let! m = mailbox.Receive ()
        let sender = mailbox.Sender ()
        let akkaName = mailbox.Self.Path.Name
        printfn "%s received message %A from %A" akkaName m sender
        sender <! Ok 0 // scheduler cannot receive this message?
        return! loop ()
    }
    loop ()

[<EntryPoint>]
let main argv =
    let actor = spawn system "TestActor" processor
    spawn system "Scheduler" (scheduler actor) |> ignore
    system.WhenTerminated.Wait()
    0

更新:

在我将参数从更改(mailbox: Actor<Result<int, string>>)(mailbox: Actor<_>)?

标签: f#akka.netakka.fsharp

解决方案


Thescheduler不是正在回复的MyTask消息的发送者processor,因为您正在<!从 Actor 计算之外执行 tell ( )。这意味着它基本上是在没有发件人的情况下发送的。您可以使用Tellon 方法IActorRef与显式发送者一起发送,因为您想从参与者计算的上下文之外发送它:

actors.Tell(MyTask("Test1", "Test1"), mailbox.Self)

编辑

另一个问题是 的mailbox参数scheduler类型为Actor<Result<int, string>>,但由于Ok 0Result<int,obj>在您的上下文中推断,它与参与者类型签名不匹配,并且该消息将被忽略。当定义具有特定消息类型的参与者时,任何不同类型的消息都将被忽略。


推荐阅读