等待akka.net actor {}表达式中的F#异步任务

Oen*_*ria 5 f# akka.net

是否可以在Akka.Net actor计算中的Async <'t>上等待(不阻塞)?我想实现类似以下的东西.

actor {
  let! msg = mailbox.Receive()
  match msg with
  | Foo ->
    let! x = async.Return "testing 123" // Some async function, return just an example
    () // Do something with result
}
Run Code Online (Sandbox Code Playgroud)

Aar*_*web 4

不,您不能在演员的邮箱内使用async/或其任何变体并获得安全结果。await

每个参与者维护自己的上下文,其中包括重要的详细信息,例如上一条消息的发送者以及其他可能更改的重要状态部分。Actor 连续处理消息,因此一旦其邮箱内的调用完成,它就会立即开始处理下一条消息 - 如果您在邮箱内放置一个等待调用,Actor 将处理一条与您开始处理的消息完全不同的消息。您的等待呼叫返回的时间。

利用异步调用和参与者内部 TAP 的更好模式是使用 PipeTo 模式。看起来我们在http://akkadotnet.github.io/上还没有任何相关文档,所以我将为您提供一个真实的代码示例(C# 语言):

    public void Handle(ExplicitReplyOperation<CampaignsForAppRequest> message)
    {
        Context.IncrementMessagesReceived();
        _loaderActor.Ask(message.Data).ContinueWith(r =>
        {
            var campaigns = (IList<Campaign>)r.Result;
            message.Originator.Tell(new CampaignsForAppResponse()
            {
                AppId = message.Data.AppId,
                ActiveCampaigns = campaigns
            }, ActorRef.NoSender);
            return campaigns;
        }).PipeTo(Self);
    }
Run Code Online (Sandbox Code Playgroud)

在此示例中,我有一个TypedActor继续任务,进行一些后处理,然后使用PipeTo运算符(可以应用于任何Task对象的 Akka.NET 扩展方法)在操作后将任务结果通过管道传输到此参与者的邮箱中完成了。这样我就可以关闭我需要的任何状态,并且我的参与者可以在异步操作继续的同时继续以安全的方式处理消息。

  • 它构建了一个可以远程部署的表达式,即可以将actor builder中的actor代码推送到远程节点,就像erlang一样..普通的async builder无法做到这一点。 (3认同)