这是在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);
});
Run Code Online (Sandbox Code Playgroud)
问题是我们为什么要Sender在这里使用闭包?为什么不使用:
_feedFactory.CreateFeedAsync(feed.FeedUri).PipeTo(Sender);
Run Code Online (Sandbox Code Playgroud)
在此示例和文档中,它表示必须在此处使用闭包.但我认为没有任何理由这样做.
如果我们使用ContinueWith()它是合理的,在continuation中使用闭包,但不作为PipeTo()参数.
我错过了什么吗?
这里要理解两件事:
Sender不是静态属性.Sender实际上是一个函数,IActorContext它返回正在处理的当前消息的发送者.每次上下文从邮箱获取新邮件时,返回的值都会更改.
PipeTo是一个延续,当在线程池上执行该延续时,调用Sender将访问IActorContext启动任务的完全相同的对象.无法保证Sender上下文中的当前流是相同的,因为自从任务开始以来将新消息推送到actor中进行处理.
所以我们缓存Sender局部变量的值,以保证我们在执行时都瞄准PipeTo正确IActorRef.