等待akka.net actor {}表达式内的F#异步任务 [英] Awaiting an F# async task inside an akka.net actor{} expression

查看:123
本文介绍了等待akka.net actor {}表达式内的F#异步任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以在Akka.Net actor计算中等待(无阻塞)异步?我想实现与以下类似的功能.

Is it possible to wait (without blocking) on an Async<'t> within an Akka.Net actor computation? I want to achieve something similar to the following.

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
}

推荐答案

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

No you can't use async / await or any variant thereof inside an actor's mailbox and get safe results.

每个参与者都保持自己的上下文,其中包括重要的细节,例如先前消息的发件人以及可能更改的其他重要状态. Actor顺序处理消息,因此,一旦其邮箱中的呼叫结束,它便立即开始处理其下一条消息-如果您将等待呼叫放入邮箱中,则Actor将处理的消息与您开始使用的消息完全不同.等待呼叫返回的时间.

Each actor maintains its own context, which includes important details like the Sender of the previous message and other important pieces of state which might change. Actors process messages serially, so as soon as the call inside its mailbox finishes it immediately begins processing its next message - if you put an await call inside the mailbox, the actor will be processing a totally different message than the one you started with by the time your await call returns.

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

A better pattern for leveraging asynchronous calls and the TAP inside actors is to use the PipeTo pattern. It looks like we don't have any documentation for this yet at http://akkadotnet.github.io/, so I'll give you a real-world code sample (in 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);
    }

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

In this sample I have a TypedActor that continues a Task, does some post-processing, and then uses the PipeTo operator (an Akka.NET extension method you can apply to any Task object) to pipe the results of the task into this actor's mailbox once the operation is finished. That way I can close over any of the state I need and my actor can continue processing messages in a safe way while this async operation continues.

这篇关于等待akka.net actor {}表达式内的F#异步任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆