Akka.NET请求任务从未完成

本文关键字:未完成 任务 请求 NET Akka | 更新日期: 2023-09-27 17:52:35

我可能做了一些不正确的事情,但它并不明显。我有以下代码:

 namespace test
    {
        class Program
            {
             static void Main(string[] args)
                {
                    using (var system = ActorSystem.Create("MySystem"))
                    {
                        var testPassRetriever = system.ActorOf<PrintActor>();
                        var task = testPassRetriever.Ask<PrintActorMsg>(new PrintActorMsg());
                        // prevent the application from exiting before message is handled
                        task.Wait();
                        Console.WriteLine("Finished.");
                        Console.ReadLine();
                    }
                }
        }
        class PrintActorMsg{}
        class PrintActor : ReceiveActor
        {
            public PrintActor()
            {
             Receive<PrintActorMsg>(msg => Console.WriteLine("foo"));
            }
        }
}// namespace test

问题是由Ask返回的Task永远不会完成。其状态保持在等待激活状态。"Foo"确实在命令行上打印出来,所以我知道actor正在处理Print消息。我应该在重写的actor PrintMsg中做其他事情来标记任务完成吗?

Akka.NET请求任务从未完成

您使用请求模式,但从不发送消息返回。只有当从参与者接收到消息时,请求任务才会完成。(有时建议使用)告知或即发即弃模式不会这样做。

只是为了将来读者的完整性,因为OP的原始问题似乎不希望从被调用的Actor返回任何响应/结果有效负载,因此OP应该使用Tell模式,而不是Ask模式,例如,对于即发即弃的调度场景:

 class PrintActor : ReceiveActor
 {
    public PrintActor()
    {
        // Response to the message, with no response
        Receive<PrintActorMsg>(msg => Console.WriteLine("foo"));
    }
 }

在调用程序

var myActor = system.ActorOf<PrintActor>();
// One way 'fire and forget'
await myActor.Tell(new PrintActorMsg());

然而,如果要求请求-响应类型交互是必需的,那么接收参与者需要通过显式的Tell向发送者提供响应(PrintResponse是一个新的响应消息类):

 public class ResponseActor : ReceiveActor
 {
    public ResponseActor()
    {
       Receive<PrintActorMsg>(msg => {
         Console.WriteLine("foo"));
         // ... Other handling code here
         // Must return a response for an Ask
         Sender.Tell(new PrintResponse(), Self);
       });
    }
 }

And called like so

var response = await actor.Ask<PrintResponse>(new PrintActorMsg(), TimeSpan.FromSeconds(5));

注意,添加异常处理也是一个好主意。