5

这是在 Akka.NET中使用的官方示例:PipeTo()

Receive<BeginProcessFeed>(feed =>
{
    //instance variable for closure
    var senderClosure = Sender; 
    SendMessage(string.Format("Downloading {0} for RSS/ATOM processing...", feed.FeedUri));

    //reply back to the sender
    _feedFactory.CreateFeedAsync(feed.FeedUri).PipeTo(senderClosure);
});

问题是我们为什么要Sender在这里使用闭包?为什么不只使用:

_feedFactory.CreateFeedAsync(feed.FeedUri).PipeTo(Sender);

在此示例和文档中,据说必须在此处使用闭包。但我看不出有任何理由这样做。

如果我们使用ContinueWith()在延续内部使用闭包是合理的,但不作为PipeTo()参数。

我错过了什么吗?

4

1 回答 1

6

这里要理解两点:

  1. Sender不是静态属性。Sender实际上是一个函数,IActorContext它返回正在处理的当前消息的发送者。每次上下文从邮箱收到新消息时,返回的值都会发生变化。

  2. PipeTo是一个延续,当该延续在线程池上执行时,调用Sender将访问启动任务的完全相同的IActorContext对象。不能保证Sender上下文中的当前是相同的,因为自从任务开始以来,新消息被推送到参与者中进行处理。

因此,我们将 的值缓存在一个局部变量中,以保证无论何时执行Sender,我们的目标PipeTo都是正确的。IActorRef

于 2015-07-10T19:18:45.777 回答