Akka.NET 询问任务从未完成
Akka.NET Ask Task never completing
我可能做错了什么,但并不明显。我有以下代码:
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 返回的任务从未完成。它的状态停留在等待激活状态。 "Foo" 确实在命令行上打印,所以我知道演员正在处理 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());
而如果需要 Ask 请求-响应类型的交互,则接收方需要通过显式 Tell
向发送方提供响应(PrintResponse
是新的响应消息 class):
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);
});
}
}
然后这样称呼
var response = await actor.Ask<PrintResponse>(new PrintActorMsg(), TimeSpan.FromSeconds(5));
请注意,添加 exception handling 也是一个好主意。
我可能做错了什么,但并不明显。我有以下代码:
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 返回的任务从未完成。它的状态停留在等待激活状态。 "Foo" 确实在命令行上打印,所以我知道演员正在处理 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());
而如果需要 Ask 请求-响应类型的交互,则接收方需要通过显式 Tell
向发送方提供响应(PrintResponse
是新的响应消息 class):
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);
});
}
}
然后这样称呼
var response = await actor.Ask<PrintResponse>(new PrintActorMsg(), TimeSpan.FromSeconds(5));
请注意,添加 exception handling 也是一个好主意。