O co w tym wszystkim chodzi?
Jeśli Twój proces biznesowy wymaga byś odczytał obiekt ze źródła danych, a następnie wykorzystał informacje w nim zawarte do odczytania kolejnych danych, będziesz potrzebował sekwencyjnych wywołań asynchronicznych.
Rozwiązanie tego typu (metoda Initialize()):
public class Sample { private FirstObject firstObj; private SecondObject secondObj; public void GetFirstObjectAsync(int id) { var service = new DummyWebService.ServiceSoapClient(); service.GetFirstObjectCompleted += (sender, e) => { firstObj = new FirstObject { Id = e.Result.Id, ChildId = e.Result.ChildId }; }; service.GetFirstObjectAsync(id); } public void GetSecondObjectAsync(int id) { var service = new DummyWebService.ServiceSoapClient(); service.GetSecondObjectCompleted += (sender, e) => { secondObj = new SecondObject { Id = e.Result.Id, }; }; service.GetSecondObjectAsync(id); } public void Initialize() { GetFirstObjectAsync(1); GetSecondObjectAsync(firstObj.Id); } }
nie zda egzaminu ponieważ metody są wykonywane asynchronicznie co oznacza, że nie wiesz, która z nich wykona się pierwsza. W naszym przypadku wymogiem jest by najpierw wykonała się metoda GetFirstObjectAsync(1), a po otrzymania rezultatu, wykonała się metoda GetSecondObjectAsync(firstObj.Id).
Wywołanie tego w synchroniczny sposób spowoduje zablokowanie aplikacji.
Najprostszym rozwiązaniem jest coś takiego:
public class Sample { private FirstObject firstObj; private SecondObject secondObj; public void GetFirstObjectAsync(int id) { var service = new DummyWebService.ServiceSoapClient(); service.GetFirstObjectCompleted += (sender, e) => { firstObj = new FirstObject { Id = e.Result.Id, ChildId = e.Result.ChildId }; GetSecondObjectAsync(firstObj.Id); }; service.GetFirstObjectAsync(id); } public void GetSecondObjectAsync(int id) { var service = new DummyWebService.ServiceSoapClient(); service.GetSecondObjectCompleted += (sender, e) => { secondObj = new SecondObject { Id = e.Result.Id, }; }; service.GetSecondObjectAsync(id); } public void Initialize() { GetFirstObjectAsync(1); } }
W ten sposób osiągniemy zamierzony efekt.
Problem pojawia się w momencie jak takich metod jest więcej. Zarządzanie takim kodem pozostawia wiele do życzenia – blah :/ ).
UWAGA:
Próba wywoływania asynchronicznie metody, wykorzystując delegata oraz jego metodę BeginInvoke() w Silverlight zakończy się wystąpieniem wyjątku NotSupportedException. Nazwa wyjątku mówi sama za siebie.
W kolejnej części postaram się pokazać jak wykonywać sekwencyjnie metody asynchroniczne przy wykorzystaniu corutines (http://pl.wikipedia.org/wiki/Wsp%C3%B3%C5%82program).
Brak komentarzy:
Prześlij komentarz