Oto the official sample korzystania PipeTo()
w Akka.NET:Dlaczego powinienem używać zamknięcia nadawcy za pomocą 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);
});
Powstaje pytanie, dlaczego powinniśmy używać Sender
zamknięcie tutaj? Dlaczego nie skorzystać po prostu:
_feedFactory.CreateFeedAsync(feed.FeedUri).PipeTo(Sender);
W tej próbce oraz w dokumentach jest powiedziane, że obowiązkowe jest tutaj zamknięcie. Ale nie widzę powodów, by to robić.
Jeśli użyliśmy ContinueWith()
, rozsądnie jest użyć zamknięcia wewnątrz kontynuacji, ale nie jako parametru PipeTo()
.
Czy coś mi brakuje?
Problem, który opisujesz pojawia się, gdy kompilator przechwytuje "to" w kontekście zamknięcia. Na przykład dzieje się, gdy używamy "tych" członków (takich jak nadawca) w wyrażeniach lambda. Ale tutaj po prostu przekazujemy parametr do metody PipeTo() i nie tworzy się zamknięć. – alexey
Nadawca jest metodą kontekstową - jego wartość zmienia się za każdym razem, gdy aktor odbierze wiadomość. Jeśli bieżąca wartość nadawcy nie jest buforowana w zmiennej lokalnej, która zostanie zamknięta podczas korzystania z PipeTo, istnieje duża szansa, że połączenie nadawcy może zwrócić wartość inną niż oczekiwany aktor. Wielokrotnie mogliśmy powtórzyć ten błąd: p – Aaronontheweb
@Aaronontheweb: "Jeśli bieżąca wartość nadawcy nie jest zapisana w pamięci podręcznej w zmiennej lokalnej, która zostanie zamknięta podczas korzystania z PipeTo". Nie ma to dla mnie sensu: to, co robi PipeTo, nie zamyka się na właściwości 'Sender', ale na zmiennej lokalnej (argument' recipient'), która jest kopią odwołania do bieżącego 'Sendera'. Dlatego nie uważam tego za coś innego niż jawne kopiowanie właściwości 'Sender' do zmiennej lokalnej. –