18/01/2009

Konsole są fajne :)

Home

Jeszcze jakiś czas temu w ogólnie nie myślałem o kupnie konsoli. Do czasu. Wczoraj zdarzyło mi się zagrać w kilka tytułów na Playstation 3. Szczególnie dobrze bawiłem się w Guita Hero. Dla niewtajemniczonych, to gra rytmiczna, w której można wcielić się w rockmana. Do gry potrzebna jest kontroler w postaci gitary, na którym w odpowiednich momentach trzeba naciskać przyciski i szarpać strony, a dokładniej coś co symuluje strunę :). Naprawdę trudno to opisać ale zabawa jest przednia. Jeszcze lepszy od gitary jest kontroler w postaci perkusji. To jest dopiero frajda. Dwie pałeczki w dłoni i walisz ile sił wlezie. Tak na marginesie seria gier Guitar Hero zarobiła ponad miliardów dolarów. Na blaszakach takich gier po prostu nie ma. W konsoli spodobało mi się jeszcze to, że wystarczy włożyć płytkę z grą napędu i można zacząć grać. Wszystko wczytuje się w maksymalnie kilkanaście sekund. I jeszcze jedna fajna rzecz. Jest dużo gier, w których można grać w dwie osoby. Na przykład w LittleBigPlanet chodzi o to aby z jednej strony zdobyć więcej punktów niż przeciwnik ale równocześnie trzeba z nim współpracować aby ukończyć planszę z powodzeniem. Jak dla mnie pomysł jest super. Zresztą wybór tytułów jest ogromny, szkoda tylko, że średnia cena to około 200 zł. Z drugiej strony konsolę kupujesz raz na kilka lat. Takie Playstation 2 jest na rynku chyba z 10. Teraz muszę się tylko zdecydować na Playstation 3 lub Xbox'a.

12/01/2009

Czemu zdarzenia nie działają ??? (część 2)

Home

W poście Czemu zdarzenia nie działają??? opisałem błąd, który doprowadza do sytuacji, w której nie otrzymujemy zdarzeń od dynamicznie tworzonych kontrolek. Jego rozwiązanie nie jest specjalnie skomplikowane i dla przypomnienia przytoczę je tutaj:

W przypadku dynamicznego tworzenia kontrolek, czy to bezpośrednio czy to przy okazji użycia kontrolek data bound zawsze należy pamiętać aby dynamiczne kontrolki były tworzone nie tylko przy inicjalnym odwołaniu do strony ale również przy kolejnych.

W tym poście chciałbym jeszcze zwrócić uwagę gdzie powinny być tworzone dynamiczne kontrolki. Najlepszym miejsce jest zdarzenie PreInit strony. Powodów jest kilka, a najważniejsze to:
  • Zdarzenie PreInit jest odpalane najwcześniej w cyklu życia strony. Jeśli stworzymy kontrolki w tym miejscu będą one dostępne w każdym kolejnym zdarzeniu - kontrolki dynamiczne będą zachowywały się tak samo jak kontrolki statycznie osadzone na stronie. To jest pierwszy i najważniejszy powód, a wszystkie wymienione dalej stanowią jego rozwinięcie.
  • Zdarzenie PreInit to jedyne miejsce, w którym możemy dynamicznie ustawić właściwość Theme. Jeśli stworzymy nasze kontrolki później to wartość tej właściwości nie będzie miała wpływu na sposób ich prezentacji.
  • Będziemy mieli zagwarantowane, że właściwości kontrolek zostaną odtworzone na podstawie ViewState.
  • Będziemy mieli pewność, że jeżeli dla dynamicznie stworzonej kontrolki ma zostać wygenerowane zdarzenie to zostanie. Innymi słowy będziemy mieli pewność, że w punkcie, w którym maszyneria ASP.NET określa dla jakiej kontrolki wywołać jakie zdarzenie, ta kontrolka będzie istnieć.
  • Takie są zalecenia :)

06/01/2009

ASP.NET Caching

Home

W poście tym chciałbym napisać kilka słów o unieważnianiu zawartości cache'a w aplikacjach ASP.NET na podstawie aktualizacji danych przechowywanych w bazie danych. Post ten nie jest jednak przewodnikiem na temat cache'owania w aplikacjach ASP.NET, opisuję w nim kilka moim zdaniem ważnych elementów. Post ten można traktować jako punkt wyjścia do dalszej nauki.

Idea jest bardzo prosta. W celu przyspieszenia aplikacji umieszczamy w cache'u jakieś dane np.: wynik zapytania czy też wyrenderowaną stronę (przy pomocy dyrektywy @OutputCache). Chcielibyśmy jednak aby w przypadku jeśli dane, na podstawie których zostało wykonane zapytanie, ulegną zmianie, ponownie wykonać zapytanie zamiast wczytywać jego wynik z cache'a. W aplikacjach ASP.NET możemy wybierać z dwóch możliwości. Jedna to obiekt klasy Cache dostępny przez właściwość strony o takiej samej nazwie. Dane umieszczone w tym pojemniku mogą zostać usunięte po upływie określonego czasu, kiedy zmianie uległ wskazy plik czy też (co interesuje nas w tej chwili) kiedy dane w bazie danych zostały zmienione. Po drugie mamy dostęp do cache'a przechowującego wyrenderowane strony czy też ich fragmenty. Z tego cache'a nie korzystamy bezpośrednio ale przy pomocy dyrektywy @OutputCache. W tym przypadku również możemy wybierać pomiędzy kilkoma wariantami unieważniania zawartości cache'a.

Przejdźmy do konkretów. W obu przypadkach aby powiązać dane w cache'u z danymi w bazie danych używamy klasy SqlCacheDependency. W przypadku cache'a dostępnego z poziomu strony musimy jawnie utworzyć instancję tej klasy. Przykład użycia znajdziemy tutaj. Natomiast w przypadku dyrektywy @OutputCache musimy użyć atrybutu SqlDependency.

Istotne jest co dzieje się pod spodem. SqlCacheDependency używa klasy SqlDependency (nazwa klasy jest taka sama jak nazwa wspomnianego wcześniej atrybutu). SqlDependency to z kolei wysoko poziomowa nakładka na inną klasę SqlNotificationRequest. Ważne jest to, że SqlDependency i SqlNotificationRequest współpracują tylko z bazą danych Sql Server 2005 i nowszymi, które dostarczają usługi powiadomień na poziomie wierszy - query notifications. To znaczy, że możemy wskazać wierszy, w przypadku zmiany których dane z cache'a zostaną usunięte. W przypadku starszych baz danych (lub nowych jeśli nie odpowiada nam query notifications) SqlCacheDependency wykorzystuje mechanizm monitorowania całych tabel zamiast wskazanej grupy wierszy. Jest to ogólnie rozwiązanie mniej wydajne.

Jeszcze parę słów o @OutputCache. Jak napisałem wcześniej aby użyć unieważniania na podstawie bazy danych należy wysterować atrybut SqlDependency. Składnia tego atrybutu jest następująca:
<%@OutputCache
...
SqlDependency="database/table name pair | CommandNotification"
...
%>
W przypadku podania pary nazwa bazy danych i nazwa tabeli zostanie użyte monitorowanie na poziomie całych tabel. W przypadku podania wartości CommandNotification zostanie użyte powiadamianie na poziomie wierszy, a dokładniej ASP.NET użyje wszystkich komend użytych w kontekście danej strony do utworzenia zależności pomiędzy danymi w cache'u, a danymi w bazie danych.

W tym momencie należy jeszcze zaznaczyć, że o ile klasa SqlCacheDependency jest właściwa dla aplikacji ASP.NET to SqlDependency i SqlNotificationRequest mogą być użyte również w innych przypadkach. W ogólności użycie SqlNotificationRequest jest raczej trudne i pracochłonne. W większości przypadków używa się SqlDependency. Przykład użycia tej klasy można znaleźć tutaj tutaj.

24/12/2008

Życzenia

Home

Życzę wszystkim aby spędzili Święta w taki sposób w jaki sobie wymarzą i z tymi ludźmi, przy których będą czuli się najlepiej.

Serdecznie pozdrawiam
Michał Komorowski

23/12/2008

Expression Studio

Home

W zeszłym tygodniu (dokładnie 17 grudnia) miałem przyjemność uczestniczyć w spotkaniu pod tytułem Nowoczesny interfejs użytkownika, oraz aplikacje web’owe - technologie i narzędzia Microsoft zorganizowanym przez firmę Microsoft. Uczestnictwo w tym spotkaniu naprawdę było przyjemnością, szczególnie jeżeli porównam je do Microsoft Technology Summit 2008, które według mnie było organizacyjną porażką, a nawet określił bym je pogardliwym mianem tzw. masówki. Spotkanie zorganizowane było w siedziby firmy Microsoft w Warszawie, a poprowadził je Artur Żarski (Developer Evangelist). W tej mini konferencji uczestniczyło około 60 osób. Prelekcja została przeprowadzono bardzo sprawnie i generalnie była ciekawa. Prelegent omówił pięć narzędzi wchodzących w skład Expression Studio:
  • Expression Media Encoder - obrabianie filmów
  • Expression Media - zarządzanie multimediami
  • Expression Web - projektowanie stron WWW
  • Expression Blend - projektowanie interfejsu użytkownika
  • Expression Designer - tworzenie grafiki wektorowej i rysunków
Dokładną charakterystykę i opis tych produktów znajdziemy na tej stronie.

Dla mnie najbardziej interesujące była cześć poświęcona narzędziom Expression Web oraz Expression Blend dlatego poświęcę im jeszcze kilka słów. Na początek należy stwierdzić, że te dwa narzędzia (zresztą pozostałe trzy podobnie) nie są przeznaczone dla programistów, a przynajmniej nie powinny być używane przez programistów. Nie powinny w tym sensie, że zalecane jest aby interfejsy użytkownika były projektowane przez wyznaczonych do tego projektantów. Oczywiście wiem jakie są realia. Napisałem tutaj o sytuacji idealnej.

Ogólnie zaleca się aby osoby/zespoły pracujące na interfejsem użytkownika były niezależne (odseparowane) względem osób/zespołów tworzących właściwą aplikację. Po pierwsze oba zadania wymagają zupełnie innych umiejętności. Po drugie dzięki takiemu podejściu osiągamy stan, w której projektanci interfejsu użytkownika nie przeszkadzają programistą i vice versa. W szczególności unikamy problemy pod tytułem: Kto zmienił nazwę tej kontrolki? Podobnie jest przy tworzeniu gier komputerowych. Modele postaci, bitmapy tworzone są przez wyspecjalizowanych grafików. Efekt ich pracy otrzymują programiści, którzy ożywiają modele, wyświetlają bitmapy, dodają efekty specjalne: oświetlenie, cienie...

Powstaje pytanie co należy stworzyć najpierw. Moim zdaniem należy pamiętać, że interfejs użytkownika to nie tylko wygląd kontrolek, ikony, kolory itd. ale również ergonomia, odpowiednie rozłożenie kontrolek i organizacja przepływu sterowania. Wydaje się, że elementy te powinny zostać zdefiniowane w pierwszej kolejności tak aby programiści znali je już na samym początku pracy. Unikamy potrzeby przebudowy kodu na późniejszym etapie pracy, a w szczególności unikamy sytuacji, w której nad tym samym elementem interfejsu pracuje równocześnie programista i projektant UI. Dlatego jestem zwolennikiem podejścia, w którym interfejs, a już napewno jego projekt/opis, powstaje najpierw.

Jeśli chodzi o Expression Web to godny zauważenia jest fakt, że Microsoft zauważył PHP i dostarczył narzędzia wspierającego ten język. Zaskoczył mnie natomiast fakt, że w przypadku aplikacji ASP.NET nie jest wspierany model code behind!.

Trochę głupio przyznać ale zaskoczyła mnie również informacja, że Expression Blend to aplikacja komercyjna (czytaj płatna). Do tej pory korzystałem bowiem z darmowej wersji community technology preview i miałem nadzieję, że ten stan utrzyma się w wersji finalnej. Szkoda, bo aplikacja ma ogromne możliwość i umożliwia wyczarowanie naprawdę fajnych efektów przy użyciu XAML'a - niektórych rzeczy nie da się po prostu zrobić czysto programistycznie, no chyba, że ktoś potrafi wyobrazić sobie wszystko w głowie.