【问题标题】:Actor cannot receive message sent to `mailbox.Sender ()`?Actor 无法接收发送到`mailbox.Sender()` 的消息?
【发布时间】:2018-10-03 14:33:52
【问题描述】:

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

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

但是演员scheduler收不到消息Ok 0

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&lt;Result&lt;int, string&gt;&gt;)更改为(mailbox: Actor&lt;_&gt;)后它工作?

【问题讨论】:

    标签: f# akka.net akka.fsharp


    【解决方案1】:

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

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

    编辑

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

    【讨论】:

    • 我用mailbox.Self 试过了,但还是不行。但是,在我将参数从 (mailbox: Actor&lt;Result&lt;int, string&gt;&gt;) 更改为 (mailbox: Actor&lt;_&gt;) 后它可以工作?
    • 哦,对了。您的演员类型也限制了该演员可以接收的消息。 Ok 0 可能被推断为 Result&lt;int,'a&gt;Result&lt;int,obj&gt;,因此即使发送者正确,也无法收到。如果您将发送消息的代码更改为将Ok 0 显式键入为Result&lt;int, string&gt;,那么您原来的actor 类型定义可能会起作用。
    • 顺便说一句,我发现没有必要使用actors.Tell(MyTask("Test1", "Test1"), mailbox.Self)sender &lt;! Ok 0 工作正常。即使将类型参数更改为Actor&lt;_&gt;,我的真实代码仍然无法正常工作。仍在调查中。
    猜你喜欢
    • 1970-01-01
    • 2021-09-11
    • 2016-05-09
    • 2016-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多