Actor无法接收发送到`mailbox.Sender()`的消息吗?

时间:2018-10-03 14:33:53

标签: f# akka.net akka.fsharp

我创建了以下测试代码-.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<_>)后可以使用吗?

1 个答案:

答案 0 :(得分:1)

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

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

编辑

另一个问题是mailbox的{​​{1}}参数键入为scheduler,但是由于在您的上下文中Actor<Result<int, string>>会被推断为Ok 0,它与actor类型签名不匹配,该消息将被忽略。当使用特定消息类型定义参与者时,任何其他类型的消息都将被忽略。