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中做其他事情来标记任务完成吗?
您使用请求模式,但从不发送消息返回。只有当从参与者接收到消息时,请求任务才会完成。(有时建议使用)告知或即发即弃模式不会这样做。
只是为了将来读者的完整性,因为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));
注意,添加异常处理也是一个好主意。