Czy zastanawialiście się kiedyś jak należy obsługiwać poprawnie Taski w Windows Phone 7? Przeglądając przykłady na MSDN w większości przypadków można spotkać następującą konstrukcję:
Task task = new Task(); try { task.PropertyA = "A"; task.PropertyB = "B"; task.PropertyC = "C"; task.Show(); } catch (System.InvalidOperationException ex) { MessageBox.Show("An error occurred."); }
Czasami nawet można spotkać się ze stwierdzeniem, że obsługa wyjątków nie jest wymagana. Stwierdzenie to nie jest prawdziwe.
using Microsoft.Phone.Tasks; … SmsComposeTask smsComposeTask = new SmsComposeTask(); smsComposeTask.To = "2065550123"; smsComposeTask.Body = "Try this new application. It's great!"; smsComposeTask.Show();
Problem pojawia się też w sytuacji, gdy chcemy dowiedzieć się w jakich sytuacjach wyrzucany jest wyjątek InvalidOperationException. MSDN milczy na ten temat. Przeglądając dokumentację zarówno całej klasy danego Taska, jak również metody Show() nie znajdziemy nigdzie informacji, że może stać się coś niepokojącego.
Do tej pory udało mi się znaleźć trzy scenariusze, w których jest wyrzucany wyjątek InvalidOperationException:
[list]
- metoda Show() wywoływana jest kilkakrotnie przed poprawnym zakończeniem jej wcześniejszego wywołania – otrzymamy następujący komunikat: Not allowed to call Show() multiple times before a Chooser returns. Ta sytuacja występuje dosyć powszechnie. Wystarczy, że użytkownik przez przypadek naciśnie kilkakrotnie przycisk odpowiedzialny za wywołanie jakiegoś Taska. Bardzo często aplikacje nie są testowane na takie zachowanie użytkowników. Wystąpienie w tym miejscu błędu powoduje zamknięcie aplikacji.
- metoda Show() wywoływana jest w momencie, w którym trwa jeszcze obsługa nawigacji – otrzymamy wtedy następujący komunikat w wyjątku: Not allowed to call Show() when a navigation is in progress. Doprowadzenie do wystąpienia tego typu wyjątku jest takie samo jak w pierwszym przypadku.
- ostatni scenariusz powiązany jest bardzo blisko z poprzednimi. Aby wywołać ten błąd należy też kilkakrotnie uruchomić Task, np. poprzez dwukrotne szybkie klikniecie na przycisk, który go uruchamia. W tym przypadku otrzymamy następujący komunikat: Navigation is not allowed when the task is not in the foreground.
[/list]
To który scenariusz zostanie wykonany zależy od momentu naciśnięcia przycisku.
Ze względu na fakt, że wszystkie scenariusze występują w większości przypadków przez błędne działania użytkownika bardzo często można spotkać się z propozycją, aby po prostu pominąć wyjątek InvalidOperationException w momencie jego wystąpienia:
Task task = new Task(); try { task.PropertyA = "A"; task.PropertyB = "B"; task.PropertyC = "C"; task.Show(); } catch (System.InvalidOperationException ex) { }
W większości przypadków zgadzam się z zaproponowaną sugestią, ale wyłącznie w sytuacji, gdy jestem pewien zaimplementowanego rozwiązania. Należy pamiętać, że opisywane błędy mogą być spowodowane nie tylko nietypowym zachowaniem użytkownika, ale również błędami w implementacji. W sytuacji, gdy programista zacznie zmieniać stronę, na której jest – uruchomi nawigację, a następnie wywoła metodę Show(), wystąpi wtedy opisywany wyjątek.
Na koniec zostawiłem najciekawsze. Metoda Show() potrafi również wyrzucić wyjątek typu ArgumentOutOfRangeException. Niestety w MSDN nie udało mi się znaleźć nigdzie informacji na ten temat. Również Google milczy w tej kwestii. Szukając wiadomości otrzymanej razem w wyjątkiem – The size of input should not exceed 64K – otrzyma się tylko jeden rezultat.
Wyjątek ten jest rzucany bardzo rzadko. Można nawet powiedzieć, że prawie nigdy. Pojawia się on tylko w sytuacji, gdy przekazane parametry do Taska po serializacji zajmują więcej niż 65536 bajtów. W większości wypadków jest to wręcz nieprawdopodobne. Są jednak Taski, w których taka sytuacja jest możliwa i powinniśmy być jej świadomi. Przykładem takiego Taska może być EmailComposeTask. Jeśli tylko nasza wiadomość, którą chcemy wysłać będzie wystarczająco długa to możemy spodziewać się wystąpienia tego wyjątku.
Podsumowując, każdy programista powinien być świadomy jak działa jego aplikacja i jakie może generować błędy. Obsługa nietypowych sytuacji powinna być dostosowana do przewidywanych scenariuszy, które mogą spowodować błąd. Nigdy też nie należy zakładać, że użytkownik zawsze będzie zachowywał się racjonalnie. Ostatnim elementem jest śledzenie informacji o wyjątkach na AppHubie i odpowiednio szybka reakcja na ich pojawienie się.
Zostaw komentarz