为什么我应该使用PipeTo()使用Sender闭包?

时间:2015-07-10 09:24:52

标签: c# akka akka.net

在Akka.NET中使用PipeTo()的{​​{3}}:

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()参数。

我错过了什么吗?

1 个答案:

答案 0 :(得分:5)

这里要理解两件事:

  1. Sender不是静态属性。 Sender is actually a function on the IActorContext返回正在处理的当前消息的发件人。每次上下文从邮箱获取新邮件时,返回的值都会更改。

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

  3. 因此,我们将Sender的值缓存在局部变量中,以确保我们在执行时PipeTo瞄准IActorRef