Showing posts with label Visual Studio. Show all posts
Showing posts with label Visual Studio. Show all posts

02/03/2010

Warszawskie Dni Informatyki 2010

Home

Zapraszam na konferencję Warszawskie Dni Informatyki 2010 oraz na moją sesję podczas, której opowiem, a przede wszystkim pokażę jedną z najciekawszych nowości w Visual Studio 2010 - IntelliTrace!


18/06/2009

Xslt jako język programowania

Home

Ostatnio sporo czasu poświęcam poznawaniu nowych narzędzi w Visual Studio 2010 czyli pożytecznej zabawie. Przy tej okazji uczę się również czasami czegoś na temat starszych wersji tego środowiska. Na przykład niedawno zajmowałem się narzędziami wspierającymi pracę z szeroko pojętym Xml'em, a w szczególności z transformacjami Xsl. Obok rzeczy wręcz oczywistych takich jak podświetlenie składni, podpowiadanie - IntelliSense znajdziemy również: profiler, debugger czy podgląd wyniku działania transformacji. Co ciekawe narzędzia te, oprócz profilera, znajdują się również w Visual Studio 2005/2008. Muszę przyznać, że do tej pory nie zdawałem sobie sprawy z tego, że Visual Studio traktuje Xslt jako "normalny" język programowania. Co tu dużo mówić, człowiek uczy się całe życie.

Dla tych co żyli w niewiedzy tak jak ja kilka zdań na ten temat. Zaczynamy od otworzenia pliku z definicją transformacji (z rozszerzeniem *.xslt) albo od dodania go do projektu. We właściwościach otwartego dokumentu (zakładka Properties) mamy do wypełnienia dwa pola: Input oraz Output. W pierwszym wskazujemy dokument Xml do przekształcenia, a w drugim plik wynikowy.



Analogicznie można zacząć od otworzenia pliku Xml. W tym przypadku na zakładce Properties będziemy mieli do wypełninia pola: Stylesheet oraz Output. W pierwszym wskazujemy plik z transformacją, a znaczenie drugiego jest takie same jak wcześniej.

W momencie kiedy mamy otworzony plik z transformacją albo plik Xml na pasku menu pojawi się element o nazwie XML.



Z tego menu może po pierwsze wybrać polecenie Show XSLT Output, które odpali transformację i pokaże nam jej wynik. Dużo ciekawsze jest jednak polecenie Debug XSLT, które umożliwia śledzenie wykonania transformacji.

Pułapki umieszczamy w kodzie transformacji dokładnie w taki sam sposób jak w kodzie programu napisanego w C#. Co więcej pułapki możemy też postawić w dokumencie Xml. Funkcji tej można użyć kiedy interesuje nas ściśle określony węzeł w dokumencie i chcemy aby debugger zatrzymał się kiedy będzie przetwarzany. Bardzo przydatne jest to, że na bieżąco możemy obserwować jak generowany jest plik wynikowy. Kod transformacji lub dokument Xml możemy teoretycznie modyfikować w czasie działania transformacji ale nie odniesie to żadnych skutków.



W Visual Studio 2010 pojawiła się jeszcze możliwość profilowania transformacji (w menu XML dodane zostało polecenie Profile XSLT). Możemy sprawdzić, wykonanie której część kodu transformacji zajmuje najwięcej czasu itd. Okno z raportem z wynikami profilowania zostało przedstawione poniżej:


02/06/2009

Problemy z instalatorem

Home

A problem has been encountered while loading the setup components. Canceling setup

Komunikat ten, objaśniający bardzo dokładnie przyczynę błędu ;), napotkałem próbując doinstalować do Visual Studio 2008 Team System komponenty związane z obsługą języka C++. Rozwiązanie problemu okazało się trywialne ale dojście do niego zajęło mi trochę czasu.

Rozwiązywanie problemu rozpocząłem od sprawdzenia czy w katalogu z plikami instalacyjnymi znajdują się inne pliki z setup w nazwie lub podobne i czy można je uruchomić. Kiedy to nie pomogło skopiowałem cały katalog z instalatorem i potrzebnymi plikami na dysk lokalny przyjmując, że problem może wynikać z tego, że uruchamiam go z dysku zdalnego. Niestety ale to również nie pomogło.

Zacząłem szukać pomocy u pana Google. Natrafiłem na forum, na którym radzono aby po prostu odinstalować środowisko i wszystkie jego komponenty, a następnie zainstalować je jeszcze raz. Pewnie by podziałało ale nie chciałem poświęcać cennego czasu na ponowne instalowanie wszystkiego czego potrzebuję.

Po dalszych poszukiwaniach znalazłem wskazówkę mówiącą abym poszukał w katalogach tymczasowych logów instalatora i zobaczył co się w nich znajduje. Rada była o tyle mało użyteczna, że nie zawierała informacji gdzie dokładnie szukać plików i jak się nazywają. Uruchomiłem więc Process Monitor i zacząłem przeglądać jakie pliki otwiera instalator VS. W moim przypadku nazywały się: dd_install_vs_vstdcore_90.txt oraz dd_error_vs_vstdcore_90.txt i znajdowały się w katalogu:
C:\Documents and Settings\username\Local Settings\Temp
W jednym z plików znalazłem wpisy zawierające tekst ERRORLOG EVENT, coś w tym rodzaju:
[06/02/09,12:25:45] setup.exe: ***ERRORLOG EVENT*** : ISetupModule::SetManager() failed in ISetupManager::LoadSetupObjectGuid() : vs_setup.dll
Nie zastanawiając się długo wrzuciłem treść loga do Googla i jak to zwykle otrzymałem dużoooooooo wyników. Jedna z pierwszych stron, zresztą forum MSDN, dotyczyła VS 2005 ale wyglądała obiecująco. Wyczytałem na niej, że problem ustępuje po wyłączeniu antywirusa, a dokładniej programu firmy Kaspersky. Korzystam co prawdy z produktu konkurencji ale stwierdziłem, że nie zaszkodzi spróbować. Niestety ale i to rozwiązanie okazało się chybione. Kiedy już prawie straciłem nadzieję kilka pozycji niżej na liście wyników znalazłem ten post. Żeby nie przedłużać rozwiązanie problemu to:

W przypadku Visual Studio 2008 z zainstalowanym service pack'iem pierwszym (nie wiem jak z kolejnymi) instalator należy uruchamiać z poziomu okna Add or Remove Programs w panelu sterowania.

11/05/2009

Visual Studio 2010

Home

Kilka dni temu, 6 maja, byłem na forum architektów, na którym między innymi pokazano wersję pre-beta Visual Studio 2010. Mówiono również o innych rzeczach ale część dotycząca nowej wersji tego środowiska była, przynajmniej dla mnie, zdecydowanie najciekawsza. Być może ta zasługa, jak zawsze rewelacyjnego Tomasza Kopacza ale nowe funkcjonalności wyglądały naprawdę bardzo obiecująco. Pozwolę sobie wymienić niektóre z nich:
  • UI oparte w całości o WPF
  • Dodano nowy sposób wyszukiwania w IntelliSense. W obecnej chwili po wpisaniu na przykład frazy Add IntelliSense poda wszystkie typy, metody itd. zaczynające się od tej frazy. W VS 2010 poda wszystkie typy, metody itd. zawierające podaną frazę czyli Add, AddTo ale również TestAdd, SuperAddTo.
  • Podgląd hierarchii wywołań pokazujący co wywołuje dana metoda i dalej co wywołują te metody itd.
  • Dynamiczne generowane diagramy sekwencji na podstawie kodu.
  • Generowanie szablonów klas. Na przykład piszemy:

    MyClass c = new MyClass();
    
    Załóżmy, że MyClass nie istnieje. W VS 2010 będziemy mogli wygenerować szablon dla tej klas. Podobny mechanizm będzie dostępny dla metod.
  • Transformacje konfiguracji. Tworzymy szablon konfiguracji i definiujemy przy pomocy specjalnego języka jak ten szablon ma zostać podczas kompilacji przekształcony w zależności od jakichś parametrów.
  • Dużo narzędzi do modelowania: integracja z Visio, powiązanie modelu z kodem na przykład po to aby kontrolować jak przebiegają prace - jakie komponenty zostały już zaimplementowane. Dalej kontrola poprawności kodu na podstawie modelu np.: czy nie ma zależności pomiędzy warstwami prezentacji i danych.
  • Lepsze narzędzia do pracy z aplikacjami wielowątkowymi. Profiler pokazujący jak działa nasza aplikacja wielowątkowa, który wątek generuje największe obciążenie, jak rozkłada się obciążenie na rdzenie/procesory. Narzędzia do radzenia sobie z zakleszczeniami.
  • Impact Analysis - Powiązanie testów z metodami, których dotyczą. Po modyfikacji metody wiemy, które testy należy powtórzyć.
  • Narywanie testów UI aplikacji okienkowych (WPF, Win Forms) - narzędzie oparte o Microsoft UI Automation. Testy takie można było pisać do tej pory tylko ręcznie.
Na koniec zostawiłem sobie dwa hity:

Historyczny debugger!!! Podczas debugowania będzie można podejrzeć jak zmieniał się stan aplikacji w różnych chwilach czasowych.

Nagrywanie stanu aplikacji!!! Przy pomocy odpowiedniego narzędzia będzie można zrzucić stan aplikacji (u klienta) do pliku i potem wczytać go do VS 2010 i rozpocząć debugowanie (potrzebny .NET 4.0).

Zaznaczam, że nie wiem jak te i inne rzeczy będą finalnie zapakowane w pudełka i sprzedawane. Z ciekawostek dodam, że Microsoft używa VS 2010 od początki roku 2008, a prace nad VS 2012 trwają już od roku :). Niby to nic dziwnego bo jak lepiej przetestować środowisko niż korzystając z niego, a prace nad tak złożonym programem muszą trwać. Ale jak sobie pomyślę, że ludzie z Microsoftu pracują teraz z/nad zabawkami, które poznam za parę lat, a zacznę z nimi pracować pewnie jeszcze później to co tu dużo mówić, ja też tak chcę!!!.

17/04/2009

Bug w Visual Studio?

Home

W poście pisałem o bardzo ciekawej i użytecznej funkcjonalności Visual Studio umożliwiającej testowanie kodu bezpośrednio z poziomu środowiska bez potrzeby pisania programów testowych. Dzisiaj w pracy chciałem skorzystać z tej możliwości, a dokładniej chciałem z poziomu okna Class View utworzyć obiekt i umieścić go w oknie Object Test Bench. Służy do tego polecenie menu kontekstowego Create Insance. Wybrałem konstruktor domyślny i ku mojemu zdziwieniu otrzymałem okienko błędu, którego nigdy wcześniej nie widziałem, z mniej więcej takim komunikatem:

The type name 'ClassName' does not exist in the type 'Test.Test'

Po bliższym przyjrzeniu okazało się, że błąd spowodowany jest tym, że klasa obiektu, który chciałem utworzyć znajduje sie w przestrzeni nazw, która zawiera inną klasę o takiej samej nazwie jak nazwa przestrzeni np.:

namespace Test
{
  public class Test
  {
  }
}
Podobny błąd występuje również przy próbie wywołania metody statycznej z poziomu okna Class View (polecenie Invoke Static Method). Aby pozbyć się problemy wystarczy zmienić nazwę przestrzeni lub klasy. Co ciekawe wygląda na to, że występowanie problemu związane jest typem projektu. Ja zauważyłem go dla projektu konsolowego. Dla projektu typu Class Library już nie. Na sieci znalazłem informacje, że taki komunikat może pojawiać się również w innych scenariuszach dla projektów innego rodzaju. Dodam jeszcze, że błąd zaobserwowałem w Visual Studio 2008.

09/04/2009

Visual Studio i za długie ścieżki

Home

Możliwe, że to znany problem ale ja natknąłem się na niego ostatnio. Otóż siedzę sobie i koduję, oczywiście używając Visual Studio i w pewnym momencie zdecydowałem, że potrzebuję z bazy kodów (aktualnie używam Visual Source Safe) pobrać nowy projekt. Sprawa prosta, wybrałem polecenie Add -> Existing Project..., wyszukałem interesujący mnie projekt, wybrałem Ok i... Visual Studio kaput. Bez żadnego ostrzeżenia, komunikatu środowisko zostało zamknięte. No cóż, myślę sobie, spróbuję jeszcze raz. Za drugim, trzecim razem dokładnie to samo. Sprawa dziwna bo inne projekty pobierają się bez problemu. Zaczynam się zastanawiać i nagle przebłysk, że chyba słyszałem o czymś takim, o jakimś problemie z długością ścieżek. Kilka eksperymentów i okazało się, że problem występuje jeżeli pełna ścieżka do pliku z projektem umieszczonym w bazie kodów przekracza 120 znaków. Jak sobie z tym poradzić. Nie pozostaje nic innego jak pobrać projekt na dysk przy pomocy Visual Source Safe Explorer i wczytać go z tej lokalizacji. Dalej Visual Studio już sobie poradzi.

22/02/2009

Zakamarki Visual Studio (cz. 4)

Home

W czwartym już poście dotyczącym różnych ciekawych funkcji środowiska programistycznego Visual Studio chciałbym przyjrzeć się dokładniej oknu Call Stack, a przy okazji poruszyć kilka innych tematów.

Okno Call Stack, breakpoint'y...

Czym jest breakpoint zapewne każdy programista wie, a jeśli nie to wstyd. Z drugiej strony nie jestem już taki pewny czy każdy programista zna wszystkie możliwości breakpoint'ów w Visual Studio: filtrowanie, warunki, zliczanie, uruchamiania makr czy wstawienie breakpoint'a do metody, której kodu nie znamy (o tym pisałem tutaj). Opisanie tych rzeczy to temat na oddzielny post. W tym miejscu skupmy się na użyciu pułapek w oknie Call Stack.

Po pierwsze umożliwia ono wstawianie breakpoint'ów. W tym celu wybieramy interesującą nas ramkę (metodę), zaznaczamy ją i naciskamy przycisk F9 (albo wywołujemy menu kontekstowe i wybieramy Breakpoint -> Insert Breakpoint). Breakpoint pojawi się zarówno w oknie Call Stack jak i na marginesie edytora kodu. W odwrotnym scenariuszu breakpoint postawiony w kodzie pojawi się w oknie Call Stack dopiero kiedy spowoduje zatrzymanie aplikacji. W każdej metodzie może zostać umieszczony wiele pułapek i trudno by je wszystkie umiescić w oknie Call Stack.

Przy pomocy okna Call Stack można również zarządzać pułapkami czyli określić warunek zatrzymania, filtr, wyłączyć pułapkę itd. W tym celu klikamy prawym przyciskiem wybraną pułapkę, z menu kontekstowego wybieramy Breakpoint, dalej interesującą nas komendę np.: Disable Breakpoint w celu wyłączenia pułapki lub Condition... w celu określenia warunku zatrzymania się pułapki.



Okno Call Stack umożliwia również ustawienie punktu śledzenia (ang. tracepoint). Tracepoint to w gruncie rzeczy specjalny breakpoint, który nie powoduje zatrzymania wykonania ale wypisanie komunikatu do okna Output. W celu ustawienie tracepoint z poziomu okna Call Stack wywołujemy menu kontekstowe i wybieramy Breakpoint -> Insert Tracepoint. Ustawienie punktu śledzienia z poziomu edytora kodu rozpoczyna się od ustawienia zwykłego brakpoint'a. Następnie należy wywołać menu kontekstowe, dalej wybrać When Hit... (sposób ten działa również w przypadku okna Call Stack). W oknie, które pojawi się zaznaczamy pola wyboru jak na rysunku:

Jeśli nie zaznaczymy pola wyboru Continue execution utworzymy zwykły breakpoint, który dodatkowo będzie powodował wypisanie komunikatu do okna Output. Tracepoint'y reprezentowane są przez romby:

W polu tekstowym okna When Breakpoint Is Hit możemy wpisać dowolny tekst, wyświetlić dowolną zmienną lub użyć jednego ze specjalny słów kluczowych. Ale po kolei. Aby wyświetlić zmienną należy wpisać { nazwa }. Słowa kluczowe wpisujemy natomiast po znaku $. Na przykład $PID służy do wypisania identyfikatora procesu. Nie będę omawiał wszystkich słów kluczowych ponieważ, jak widać na powyższym rysunku, ich opis można znaleźć w oknie When Breakpoint Is Hit. Zwrócę tylko jeszcze uwagę na bardzo ciekawą możliwość wyświetlenia stosu przy pomocy słowa kluczowego $CALLSTACK oraz na to, że przy tworzeniu komunikatu jesteśmy ograniczeni tylko do jednej linii.

Run To Cursor

Run To Cursor to bardzo znane polecenie, które umożliwia rozpoczęcie debugowania i wskazanie miejsca w kodzie, w którym debugger ma się zatrzymać (pod warunkiem, że nie zatrzyma się wcześniej z powodu breakpoint'a). Niewiele osób jednak wie, że polecenie to jest dostępna z poziomu okna Call Stack. Pozwala wskazać, do którego miejsca chcemy zwinąć stos. Wystarczy wybrać interesującą nas ramkę/metodę i z menu kontekstowego wybrać tę komendę.

Wartość argumentów

Inną bardzo fajną cechą okna Call Stack jest to, że podaje ono wartości przekazanych do funckji argumentów. Jeśli wartości argumentów nie są widoczne powinniśmy w onie Call Stack wywołać menu kontekstowe, a następnie zaznaczyć Show Parameter Values. No dobrze, w przypadku typów prostych jest to z pewnością przydatne ale co z typami złożonymi. Domyślnie zostanie wyświetlona po prostu nazwa typu ale można to zmienić korzystając z atrybutu DebuggerDisplayAttribute. Dla tych co nie wiedzą jest to jeden z wielu atrybutów, który pozwala na dostosowanie debuggera do naszych potrzeb (kolejny dobry temat na oddzielny post, a nawet kilka :)). Najłatwiej wyjaśnić to na przykładzie. Posłużmy się kodem jak poniżej:
public class Test
{
   private int value;

   public int Value
   {
      get { return this.value; }
   }

   public Test(int value)
   {
      this.value = value;
   }
}
Wartości typu Test zostaną przedstawione w taki o to mało interesujący sposób:

ConsoleApplication.Program.Equals(a = {ConsoleApplication.Program.Test}, b = {ConsoleApplication.Program.Test})

Wystarczy jednak zmodyfikować definicję klasy Test jak poniżej:
[DebuggerDisplay("Value = {value}")]
public class Test
{
...
}
Aby osiągnąć taki efekt:

ConsoleApplication.Program.Equals(a = Value = 1, b = Value = 1

Technika ta działa nie tylko w przypadku okna Call Stack ale również w przypadku innych okien debuggera czyli np.: Quick Watch.

Unwind To This Frame

Unwind To This Frame to jedna z komend dostępna w menu kontekstowym okna Call Stack. W większości przypadków kiedy wywołamy menu jest wyszarzona. Dostępna staje się tylko w przypadku kiedy zostanie rzucony wyjątek. W momencie rzucenia wyjątki środowisko najczęściej zatrzymuje wskazując linię w kodzie, w której wyjątek został wygenerowany (w szczególności może się nie zatrzymać jeśli wyjątek został obsłużony, a my nie mamy zaznaczonej opcji zatrzymywania na wszystkich wyjątkach). W oknie Call Stack ramka, w której został rzucony wyjątek wskazywana jest przy pomocy żółtej strzałki. Jeśli wyjątek został rzucony poza naszym kodem ostatnia ramka wskazująca nasz kod zostanie oznaczona strzałką zieloną .

Kiedy środowiska zatrzyma się już z powodu wyjątku możemy w oknie Call Stack wybrać interesującą nas ramkę, wywołać menu i wybrać komendę Unwind To This Frame. Spowoduje to zwinięcie stosu do wybranej ramki (działanie podobne do Run To Cursor) i umożliwi np.: zdiagnozowanie przyczyny wyjątku, modyfikację zmiennych lokalnych tak aby wyjątek nie został rzucony itd.

Polecenie Unwind To This Frame nie jest dostępne dla wszystkich ramek. Stos można zwinąć do każdej ramki powyżej ostatniej ramki, która wskazuje miejsce w naszym kodzie (pomiędzy żółtą i zieloną strzałką :)). Czyli jeśli wyjątek został rzucony bezpośrednio w naszym kodzie polecenie będzie dostępne tylko dla jednej ramki. Z kolei dla przypadku pokazanego niżej:

System.Xml.Serialization.XmlSerializer.Deserialize(xmlReader, encodingStyle, events)
System.Xml.Serialization.XmlSerializer.Deserialize(stream)
ConsoleTest.Program.Main(args)
...


Stos możemy zwinąć do jednej z metod Deserialize() albo do metody Main() w naszym kodzie.

Omawiając tą funkcjonalność należy koniecznie napisać o exception assistant. Całkiem możliwe, że większość użytkowników Visual Studio nigdy o nim nie słyszała. W sumie nie dziwne ponieważ jest domyślnie włączony (Tools -> Options -> Debugging -> General -> Enable the exception assistant). A do czego służy? Poniżej zamieszczam okienka wyświetlone przez środowisk w momencie rzucenia wyjątku kiedy asystent jest wyłączony (pierwszy obrazek) i kiedy jest włączony (drugi obrazek):



Mam nadzieję, że zalety asystenta są oczywiste :) ale asystent to nie tylko ładne okienko. Jeśli jest włączony w momencie rzucenia wyjątki środowisko wskaże zawsze linię w naszym kodzie nawet jeżeli prawdziwe źródło wyjątku jest gdzie indziej. Dzięki temu możemy po prostu "złapać" żółtą strzałkę, wskazującą w głównym oknie ostatnio wykonaną instrukcję, i przeciągnąć ją kilka linijek wcześniej lub kilka linijek dalej. Innymi słowy możemy ominąć wyjątek lub prześledzić jak został spowodowany. Przy włączonym asystencie polecenie Unwind To This Frame staje się trochę mniej ponieważ przydatne ale czasami możemy chcieć wyłączyć asystenta. W każdym razie dobrze zdawać sobie sprawę z jego istnienia.

Opisane techniki testowałem w środowiskach Visual Studio 2005 oraz Visual Studio 2008.

03/02/2009

Zakamarki Visual Studio (cz. 3)

Home

W trzecim już poście dotyczącym zakamarków Visual Studio, czyli mało znanych funkcji tego środowiska programistycznego, chciałbym napisać o oknie Object Test Bench. Okno to pozwala na szybkie testowanie wywołań metod statycznych i instancyjnych bez potrzeby pisania małych programików testowych. Jeśli po uruchomieniu środowiska nie jest widoczne możemy je wyświetlić wybierając View->Other Widnows->Object Test Bench. Aby wygodnie pracować z tym oknem przyda się również okno Class View (View->Class View), które służy do przeglądania typów zdefiniowanych w naszych projektach oraz w innych pakietach/podzespołach (ang. assembly), do których się odwołujemy. Ważna uwaga! Widok Object Test Bench może zostać użyty tylko i wyłącznie do testowania klas w projekcie oznaczonym jako StartUp oraz w pakietach, do których ten projekt się odwołuje. Co prawda zgodnie z dokumentacją powinniśmy móc testować wszystkie klasy w bieżącym rozwiązaniu (ang. solution) ale niestety nie jest to możliwe.

Dalej będę posługiwał się prościutką, a wręcz naiwną klasą zdefiniowaną poniżej, w celu omówienia zastosowania okna Object Test Bench.
public class Person
{
 private static int count = 0;
 
 private string name;
 private DateTime dateOfBirth;

 public string Name
 {
  get { return name; }
  set { name = value; }
 }

 public DateTime DateOfBirth
 {
  get { return dateOfBirth; }
  set { dateOfBirth = value; }
 }

 public Person()
 {
  Person.count++;
 }

 public Person(string name, DateTime dateOfBirth)
 : this()
 {
  this.name = name;
  this.dateOfBirth = dateOfBirth;
 }

 public int GetAge(bool inDays)
 {
  if(!inDays)
   return DateTime.Now.Year - dateOfBirth.Year;
  else
   return (DateTime.Now - dateOfBirth).Days ;
 }

 public static int GetCount()
 {
  return Person.count;
 }
}
Aby rozpocząć testowanie jakiejś klasy musimy zlokalizować ją w oknie Class View i wywołać dla niej menu kontekstowe. W menu kontekstowym powinny być widoczne dwie komendy:
  • Create Instance - Pozwala wywołać dowolny konstruktor dla danego typu i przypisać mu identyfikator. Stworzony obiekt pojawi się w oknie Object Test Bench. Dla stworzonych obiektów możemy następnie wywoływać metody instancyjne. W ten sposób nie powołamy do życia instancji klasy abstrakcyjnej czy też delegata.
  • Invoke Static Mehtod - Pozwala wywołać wybraną metodę statyczną danej klasy (również klasy abstrakcyjnej).
Polecenia te będą widoczne tylko dla klas z projektu głównego. Oczywiście przed wywołaniem metody statycznej, instancyjnej czy też konstruktora powinniśmy w interesujących nas miejscach w kodzie ustawić breakpointy.

Zacznijmy od wywołania metody statycznej. Po najechaniu w menu kontekstowym na polecenie Invoke Static Mehtod wyświetlone zostaną wszystkie metody statyczne dostępne w tej klasie. Należy wybrać jedną z nich. W przypadku naszej klasy testowej Person możemy wybierać pomiędzy GetCount() oraz dwie metodami odziedziczonymi po klasie Object: Equals(object, object) oraz ReferenceEquals(object, object). Po wybraniu GetCount() pojawi się okno potwierdzające chęć wywołania tej metody. Natomiast w przypadku metod, które posiadają parametry pojawi się okno pozwalające na wyspecyfikowanie wartości tych parametrów. Kiedy klikniemy Ok metoda zostanie wywołana. Na zakończenie pojawi się okno z wynikiem, które powinno wyglądać jak poniżej: Istnieje również możliwość zapisania wyniku wywołania metody. W tym celu powinniśmy zaznaczyć opcję Save return value (w oknie pokazanym powyżej) i nadać identyfikator dla zwracanego obiektu/struktury. Jeśli zdecydujemy się na zapisanie wyniku pojawi się on w oknie Object Test Bench: Stworzone obiekty reprezentowane są w oknie Object Test Bench przez prostokąty. Dla każdego obiektu możemy wywołać menu kontekstowe, które pozwoli nam wybrać metodę instancyjną do wywołania. Spróbujmy wykonać metodę posiadającą parametry np.: CompareTo(int). Po jej wybraniu powinniśmy zobaczyć okno jak poniżej: Warto zauważyć, że jeżeli metoda opatrzona była komentarze to zostanie on przytoczony. Po podaniu wartości parametru aktualnego i wybraniu przycisku Ok, metoda zostanie wywołana, a wynik zostanie przedstawiony w takim samym oknie jak przy wywoływaniu metody statycznej (jego też możemy zapisać).

Przyjrzyjmy się teraz poleceniu Create Instance i stwórzmy instancję klasy Person korzystając z konstruktora dwuargumentowego. Po wybraniu konstruktora powinno pojawić się okno przedstawionej dalej: Po pierwsze powinniśmy podać nazwę dla tworzonego obiektu. W tym miejscu trzeba uważać bo jeśli podanym nazwę, której już użyliśmy zostaniemy o tym poinformowani dopiero po naciśnięciu przycisku Ok, a nie ma możliwości cofnięcia się i naprawienia błędu.

Po drugie, podobnie jak przy wywoływaniu metod, należy podać wartości poszczególnych argumentów. Napiszę o tym troszeczkę więcej. Jeśli chodzi o typy proste nie ma co się rozpisywać. Po prostu wpisujemy liczbę lub ciąg znaków (zamknięty w cudzysłowy) i koniec. Troszeczkę trudniej jest z typami złożonymi. Na rysunku widać, że dla parametru dateOfBirth wstawiłem dziwną wartość dateTime1. Niestety ale w przypadku typów złożonych musimy najpierw stworzyć instancję danego typu, a dopiero potem powołując się na przypisaną danej instancji nazwę, użyć jej jako argumentu wywołania. Nazwa stworzonej instancji pojawi się na rozwijanej liście dla argumentów o odpowiednim typie.

W tym przypadku stworzyłem uprzednio strukturę typu DateTime i nadałem jej nazwę dateTime1. Zacząłem od zlokalizowania typu struktury w drzewie (najwygodniej posłużyć się przyciskiem Search u góry okna Class View). Następnie wybrałem polecenie Create Instance, dalej zdecydowałem się na konstruktor trójargumentowy, jako argumenty wywołania podając rok, miesiąc i dzień mojego urodzenia (wszystkie wartości to typy proste). Na koniec powróciłem do klasy Person i ponownie wybrałem interesujący mnie konstruktor. Jak widać tworzenie obiektów wymagających skomplikowanej inicjalizacji jest trudne i kłopotliwe ale te okno nie do tego służy.

Po stworzeniu instancji klasy Person możemy przystąpić do testowania jej metod, a właściwie jednej metody. Odbywa się to dokładnie w ten sam sposób jak opisałem na przykładzie metody CompareTo(int). Polecam spróbować wywołać metodę GetAge(bool) z parametrem true oraz false oraz sprawdzić jaki wynik zwraca metoda statyczna GetCount() po utworzeniu instancji klasy Person.

Jeszcze dwie uwagi na koniec. Jeśli wprowadzimy jakieś zmiany do kodu to okno Object Test Bench wymusi na nas ponowną kompilację źródeł. Równoznaczne jest to z utratą wszystkich obiektów, struktur, które umieściliśmy wcześniej w tym oknie.

W drugiej części tej serii postów pisałem o oknie Immediate. W ciekawy sposób współpracuje ono z oknem Object Test Bench. Dla przypomnienia w oknie Immediate również możemy wywoływać metody i tworzyć obiekty. Istotne jest to, że obiekty, które stworzymy w tym oknie pojawią się również w oknie Object Test Bench. Tutaj też obowiązuje warunek, żeby użyty typ pochodził z projektu oznaczonego jako StartUp lub z pakietu/podzespołu, do którego tej projekt się odwołuje. Kolejny warunek jaki musimy spełnić (wygląda to na błąd w Visual Studio) jest taki, że okno Object Test Bench nie może być puste w momencie tworzenia obiektu w oknie Immediate. Jeśli będzie tworzone obiekty nie zostaną do niego dodane. Co ciekawe jeśli w pewnym momencie dodamy jakiś obiekt do okna Object Test Bench (z poziomu okna Class View) to nagle pojawią się w nim również obiekty utworzone wcześniej w oknie Immediate.

Warto jeszcze dodać, że obiekty z okna Immediate w oknie Object Test Bench będą miały takie same identyfikatory jak zmienne użyta w oknie Immediate. Czyli wpisanie takiej komendy:
Person person = new Person();
spowoduje dodanie do okna Object Test Bench obiektu o nazwie person

Opisane techniki testowałem w środowiskach Visual Studio 2005 oraz Visual Studio 2008.

24/11/2008

Zakamarki Visual Studio 2005/2008 (cz. 2)

Home

Zapraszam do zapoznania się z kolejną porcją ciekawych i mało znanych funkcji Visual Studio.

Breakpoint w pętli

Bardzo przydaną funkcją jest możliwość postawienia breakpoint'a w definicji pętli for lub foreach. Załóżmy, że mamy taki kod:
for(int i = GetValue(); i < GetLimit(); i++)
{
  ...
}
Domyślne zachowanie środowiska jest takie, że po kliknięciu linii, w której znajduje się początek pętli i naciśnięciu przycisku F9 breakpoint zostanie ustawiony na części inicjalizacyjnej pętli czyli uzyskamy taki efekt:
for(int i = GetValue(); i < GetLimit(); i++)
{
  ...
}
Czasami, a nawet częściej niż czasami chcielibyśmy aby debugger zatrzymał się w części sprawdzającej warunek pętli. Nic prostszego. Wystarczy przesunąć kursor i ponownie nacisnąć F9. Uzyskamy efekt jak poniżej:
for(int i = GetValue(); i < GetLimit(); i++)
{
  ...
}
Oczywiście debugger możemy zatrzymać również w instrukcji interacji. Podobnie możemy postąpić z pętlą foreach.

Testowanie przy pomocy okna Immediate

Ciekawym sposobem na szybkie testowanie metod statycznych jest użycie okna Immediate. Jeśli nie jest ono standardowo widoczne to znajdziemy je w Debug -> Windows. Po pierwsze okno to pozwala w czasie debugowania wywoływać metody obiektów, zmieniać ich właściwości itd. Po drugie, co jest nawet ciekawsze, umożliwia wywołanie metody statycznej kiedy środowisko nie znajduje się w trybie debugowania. Wykonanie takiej operacji spowoduje uruchomienie debugera i o ile, w metodzie statycznej znajduje się breakpoint, jego zatrzymanie. Dzięki temu nie musimy tracić czasu na pisanie krótkich programików tylko po to aby przetestować daną metodę statyczną. Po trzecie co jeszcze ciekawsze okno Immediate pozwala również w podobny sposób testować zwykłe metody klas. Załóżmy, że napisaliśmy klasę Test i zdefiniowaliśmy w niej metodę Fun(). W oknie Immediate może wpisać:
Test t = new Test(); 
t.Fun(); 
Podobnie jak wcześniej. Jeśli w metodzie znajdował się breakpoint debugger zatrzyma się na nim. Jesli nie, metoda zakończy swoje działanie. Oczywiście technika ta pozwala testować tylko stosunkowe proste scenariusze ale tak czy inaczej ułatwia i przyspiesza tworzenie dobrego kodu.

Opisane techniki testowałem w środowiskach Visual Studio 2005 oraz Visual Studio 2008.

22/11/2008

ADO.NET Data Services, Jak to ugryźć?

Home

Wszystkich zainteresowanych rozpoczęciem zabawy z technologią Microsoft'u ADO.NET Data Services (nazwa kodowa Astoria) chciałbym zachęcić do zapoznania się z serią filmików spod znaku How Do I:
Astoria umożliwia naprawdę łatwy i szybki sposób udostępniania danych z różnych źródeł w sieci (w szczególności może to być oczywiście baza relacyjna). Dostęp do danych został zorganizowany zgodnie z podejściem typu REST czyli upraszczając aby uzyskać dostęp do zasobu musimy znać jego URI. Każdy z filmików pokazuje krok po kroku jak coś zrobić przy pomocy ADO.NET Data Services. Obejrzenie każdego z nich zajmie wam kilkanaście minut (oczywiście trzeba znać język angielski). Bardziej dogłębne (i znacznie dłuższe) wprowadzenie znajdziemy tutaj Developing Applications Using Data Services. Aby rozpocząć używanie Astorii potrzebujemy Visual Studio 2008 z Service Pack 1. Wersję Express już z Service Pack 1 znajdziemy tutaj.

19/11/2008

Zakamarki Visual Studio (cz. 1)

Home

Visual Studio to potężne narzędzie, o ogromnych możliwościach, które pozwala tworzyć i debugować programy w łatwy i przyjemy sposób. Dobra znajomość swojego środowiska pracy do podstawa dla każdego programisty. Dlatego poniżej zamieszczam opis kilku "zaawansowanych" narzędzi udostępnionych w Visual Studio. Tak naprawdę prezentowane przeze mnie techniki nie są ani trudne, ani skomplikowane w użyciu. Nie ulega jednak wątpliwości, że są stosunkowo mało znane. Działają poprawnie w przypadku języka C# (dla innych języków może być inaczej).

Okienko Find

Z pewnością każdy kiedyś korzystał z tego narzędzia aby szybko wyszukać w kodzie interesującą go frazę. Ale możliwości okienka Find są znacznie większe. Po pierwsze wpisanie do niego nazwy jakieś metody i naciśnięcie przycisku F9 spowoduje wstawienie breakpoint'a do każdej metody o podanej nazwie. Moim zdaniem bardzo przydatna funkcjonalność jeśli mamy w projekcie jedną lub więcej, wielokrotnie przeciążonych metod. Do okienka Find możemy również wpisać nazwę pliku (razem z rozszerzeniem). Teraz jeśli naciśniemy kombinację Ctrl+Shift+G i plik o podanej nazwie istnieje to zostanie otworzony gotowy do edycji. Przydaje się przy dużym drzewie projektów z rozbudowaną hierarchią plików i folderów.

Podglądanie cudzych metod

Przypuśćmy przez chwilę, że pracujemy ze złośliwym programistą, który nie chce udostępnić innym swoich kodów. Przypuśćmy dalej, że w kodzie złośliwego programisty jest generowany wyjątek. Wyjątek ten powstaje głęboko w kodzie złośliwego programisty i oznacza, że do metody został przekazany ciąg znaków o błędnym formacie. Wspomniany ciąg znaków dostarczany jest przez nas i może to być np.: connection string.

Co więcej programista jest tak uparty, że twierdzi, że to nie jego wina oraz, że z pewnością przekazujemy do jego metody złe dane. Co gorsza jest na tyle sprytny, że zabezpieczył swoje biblioteki przed programem takim jak Lutz Roeder’s Reflector. Tak na marginesie to genialne narzędzie, niezbędne w pracy każdego programisty .Net. Należy jeszcze dodać, że ten programista to syn szefa :)

My wiemy swoje i on wie swoje. Nie mamy dostępu to kodu biblioteki złośliwego programisty ale oczywiście znamy stack trace. Znamy więc nazwy kolejno wołanych metod aż do wystąpienia wyjątku. Jedyna nasza szansa to udowodnić złośliwemu programiście, że nasze dane są prawidłowe i to w jego kodzie jest błąd.

I tutaj wkracza do akcji Visual Studio. Okazuje się, że można postawić breakpoint w metodzie, dla której nie mamy kodu źródłowego. Kiedy debugger zatrzyma się będziemy mogli w oknie Locals zobaczyć wartości wszystkich argumentów przekazanych do metody! W celu postawienia takiego breakpoint'u korzystamy z bardzo prostego sposobu: otwieramy okno New Breakpoint, w polu Function wpisujemy nazwę metody, naciskamy przycisk Ok i gotowe. Do okna New Breakpoint dostajemy się z poziomu standardowego okna Breakpoints (Debug -> Windows -> Breakpoints) wybierając przycisk New, a następnie polecenie Brak at Function...

Okno Call Stack

Run To Cursor to bardzo znane polecenie, które umożliwia rozpoczęcie debugowania i wskazanie miejsca w kodzie, w którym debugger ma się zatrzymać (pod warunkiem, że nie zatrzyma się wcześniej z powodu breakpoint'a). Niewiele osób jednak wie, że polecenie to jest dostępna z poziomu okna Call Stack. Pozwala wskazać, do którego miejsca chcemy zwinąć stos. Wystarczy wybrać interesującą nas metodę i z menu kontekstowego wybrać tę komendę. W bardzo podobny sposób można przy pomocy okna Call Stack postawić breakpoint. W tym celu podobnie jak wyżej wybieramy interesującą nas metodę, zaznaczamy ją i naciskamy przycisk F9 (albo wywołujemy menu kontekstowe i wybieramy Breakpoint -> Insert Breakpoint).

Podsumowanie

Mam nadzieję, że opisane przeze mnie narzędzia i techniki okażą się przydatne. W następnej części opiszę kolejną porcję ciekawych funkcji Visual Studio.

Opisane techniki testowałem w środowiskach Visual Studio 2005 oraz Visual Studio 2008.