22/07/2009

Czemu należy używać właściwości SyncRoot?

Home

SyncRoot to właściwość zdefiniowana na poziomie interfejsu ICollection służąca do synchronizowania operacji wykonywanych na kolekcjach przy pomocy słowa kluczowego lock lub jawnie przy pomocy monitora. Czemu jednak należy używać tej właściwości zamiast instancji kolekcji, czyli czemu zalecany jest taki kod:
lock(list.SyncRoot)
{
   ...
}
A nie taki?
lock(list)
{
   ...
}
Kiedy postawiłem sobie to pytanie okazało się, że odpowiedź nie jest dla mnie oczywista. Wizyta w dokumentacji MSDN nic nie pomogła bo udzielone wyjaśnienie należy do grupy tych, które stają się jasne i oczywiste jak już znasz prawidłową odpowiedź ;).

Spędziłem trochę czasu zastanawiając się nad tą kwestią oraz szperając po sieci i doszedłem do następujących wniosków. Należy używać właściwości SyncRoot ponieważ zapewnia ona centralny, dobrze określony, bezpieczny punkt synchronizacji dla kodu zewnętrznego używającego kolekcję jak i dla kodu wewnętrznego kolekcji. Inaczej mówiąc zapewnia to, że każdy kod używa tego samego obiektu do synchronizacji. Bezpieczny w tym sensie, że bardzo łatwo można stwierdzić kto i kiedy uzyskuje dostęp do obiektu synchronizacyjnego - wystarczy ustawić pułapkę w getter-ze właściwości. Synchronizacja bezpośrednio przy użyciu instancji kolekcji czy też na obiekcie this może natomiast doprowadzić to bardzo trudnych do wykrycia zakleszczeń ponieważ nie będzie można łatwo określić kto i w jakim momencie blokuje obiekt. Z drugiej strony jeśli taka semantyka SyncRoot jest z jakiegoś powodu niepożądana kolekcje wydziedziczone z kolekcji bazowej mogą dostarczyć własnej implementacji tej właściwości.

17/07/2009

$find vs $get

Home

Ostatnimi czasy pracowałem nad webową aplikacją mapową, która bardzo silnie wykorzystuje ASP.NET Ajax, a więc nie obyło się bez napisania "kilku" linii kodu w JavaScript. Przy okazji implementowania jednej z funkcjonalności musiałem odwołać się do kontrolki mapowej. Niewiele myśląc napisałem mniej więcej taki kod:
...
var map = $get(MapControlId);
...
Kontrolka oczywiście została znaleziono. Zgodnie z dokumentacją powinna udostępniać funkcję toMapPoint konwertującą współrzędne ekranowe na mapowe. Niestety ale okazało się, że taki kod nie działa ponieważ znaleziona kontrolka nie udostępnia takiej metody.
...
var res = map.toMapPoint(x, y);
...
Moment konsternacji, dokumentacja mówi jedno, a życie pokazuje drugie. Chwila szukania w Internecie i rozwiązanie problemu jak zwykle okazało się trywialne. Zamiast funkcji $get należy użyć funkcji $find. Czym się różnią? Pierwsza z nich to po prostu skrót do użycia dobrze znanej funkcji getElementById służącej do wyszukiwania elementów DOM o podanej wartości atrybutu id.

Funkcja $find służy natomiast do wyszukiwania komponentów o stanowi skrót dla wywołania findComponent. Komponent to moduł programowy udostępniający jakąś funkcjonalność. Komponenty dzielimy na trzy kategorie. Po pierwsze mamy komponenty niewizualne takie jak zegar (ang. timer). Pozostałe dwa typy komponentów w ASP.NET Ajax to kontrolki czyli komponenty wizualne (elementy DOM) oraz zachowania (ang. behaviours), które rozszerzają możliwości istniejących już elementów DOM. Metoda, której potrzebowałem użyć była oczywiście zdefiniowana na komponencie, a nie na elemencie DOM.

03/07/2009

'ltr' -> 'rtl'

Home

Wszyscy jesteśmy przyzwyczajeni do pisania i czytania od lewej do prawej. Przyjmujemy jako pewnik, że menu Start znajduje się w lewym dolnym rogu ekranu, krzyżyk służący do zamykania okna w prawym górnym rogu okna, a krzyżyki służące do rozwijania węzłów w drzewie umieszczane są z lewej strony węzłów itd. Dlaczego o tym piszę? Niedawno zajmowałem się przystosowaniem aplikacji WWW do kultur o orientacji od prawej do lewej. Na warsztat wziąłem kulturę hebrajską. Zainstalowałem odpowiedni pakiet do Windows XP i po przełączeniu ustawień regionalnych i językowych opadła mi szczęka :) Wszystko zostało odwrócone: ikony na pulpicie, położenie poleceń w menu, przycisk Backspace działa jak Delete, po naciśnięciu strzałki w prawo kursor przesuwa się w lewo, menu start jest w prawym dolnym rogu, strzałka do rozwijania list z lewej strony itd. Mały przykład poniżej:



Wracając jednak do aplikacji WWW. Okazuje się, że przestawienie aplikacji w tryb Right to Left jest banalnie proste i sprowadza się do dodania atrybutu dir o wartości 'rtl' na przykład do tagu html. Całą resztą zajmie się przeglądarka (testowałem w IE7 oraz Operze). Poniżej porównanie prostego układu w dwóch orientacjach. Jak widać układ z prawej strony stanowi lustrzane odbicie tego z lewej.



W dużej, komercyjnej aplikacji po zmianie orientacji zauważyłem niewielkie błędy ale można je z pewnością łatwo wyeliminować. W każdym razie wkładając minimum wysiłku można bardzo prosto przełączyć aplikację WWW w tryb od prawej do lewej.