下面是Akka.NET使用PipeTo()
的the official sample:爲什麼我應該使用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()
,那麼在continuation中使用closure是合理的,但不應該使用PipeTo()
參數。
我想念什麼?
您所描述的問題,當編譯器捕獲在封閉的環境下「本」出現。例如,當我們在lambda表達式中使用「this」成員(如Sender)時會發生這種情況。但是在這裏我們只是將參數傳遞給PipeTo()方法,並且沒有創建閉包。 – alexey
發送者是一種上下文敏感的方法 - 每次演員收到消息時,它的值都會發生變化。如果發件人的電流值不會在一個局部變量,它被當您使用PipeTo在關閉緩存,有一個強大的機會,你的發件人的呼叫可以返回比你預期的演員不同的值。 我們已經能夠複製這種錯誤了無數次:對 – Aaronontheweb
@Aaronontheweb:「如果發件人的電流值不會在一個局部變量,當您使用PipeTo它被關閉了緩存」。這對我沒有意義:PipeTo所做的是不是關閉Sender屬性,而是關閉一個局部變量(參數'recipient'),它是當前Sender引用的副本。因此,我不認爲這與將'Sender'屬性明確複製到局部變量中不同。 –