W poście tym chciałbym zachęcić do używania darmowego narzędzia Process Monitor, które umożliwia monitorowanie wszelkiej aktywności w systemie operacyjnym dotyczącej zasobów takich jak: pliki, klucze rejestru, połączenia sieciowe itd.
Pożytki płynące z tego narzędzia opiszę na swoim przypadku. Ostatnio napisałem prostą bibliotekę, która parsuje plik Xml, przetwarza jego zawartość przy pomocy transformacji Xsl w celu stworzenia plików Html i finalnie uruchamia kompilator pomocy w celu wytworzenia pliku chm. Biblioteka nie jest skomplikowana i bardzo szybko udało się uzyskać pożądany efekt (prawie). Niestety ale okazało się, że kompilator pomocy nie potrafi przetworzyć wszystkich plików Html i generuje dla nich błąd HHC5003: Error: Compilation failed while compiling... Co ciekawe efekt ten był obserwowany tylko w przypadku programowego uruchomienia kompilatora przy pomocy klasy Process. Przy ręcznym uruchamiania wszystko działało prawidłowo. Po bliższym przyjrzeniu okazało się, że kompilator zgłaszał błędy zawsze dla tych samych plików. W przypadku kiedy lista plików została powiększona błąd zaczął być zgłaszany dla nowych plików! Pliki, które wcześniej zdawały się nieprawidłowe okazywały się nagle jak najbardziej w porządku.
Nie udało mi się znaleźć dokładnych informacji na temat zgłaszanego przez kompilator błędu z wyjątkiem tego, że przyczyną może być brak dostępu do pliku. Postanowiłem więc przyjrzeć się procesowi kompilacji przy pomocy Process Monitor'a. Ponieważ aplikacja w trybie domyślnym wyświetla ogromną ilość danych (setki tysiące wierszy) postanowiłem skupić się tylko na wpisach dotyczących jednego z plików, dla których kompilator zgłaszał błąd. Po włączeniu filtrowania uzyskałem taki wynik:
Pożytki płynące z tego narzędzia opiszę na swoim przypadku. Ostatnio napisałem prostą bibliotekę, która parsuje plik Xml, przetwarza jego zawartość przy pomocy transformacji Xsl w celu stworzenia plików Html i finalnie uruchamia kompilator pomocy w celu wytworzenia pliku chm. Biblioteka nie jest skomplikowana i bardzo szybko udało się uzyskać pożądany efekt (prawie). Niestety ale okazało się, że kompilator pomocy nie potrafi przetworzyć wszystkich plików Html i generuje dla nich błąd HHC5003: Error: Compilation failed while compiling... Co ciekawe efekt ten był obserwowany tylko w przypadku programowego uruchomienia kompilatora przy pomocy klasy Process. Przy ręcznym uruchamiania wszystko działało prawidłowo. Po bliższym przyjrzeniu okazało się, że kompilator zgłaszał błędy zawsze dla tych samych plików. W przypadku kiedy lista plików została powiększona błąd zaczął być zgłaszany dla nowych plików! Pliki, które wcześniej zdawały się nieprawidłowe okazywały się nagle jak najbardziej w porządku.
Nie udało mi się znaleźć dokładnych informacji na temat zgłaszanego przez kompilator błędu z wyjątkiem tego, że przyczyną może być brak dostępu do pliku. Postanowiłem więc przyjrzeć się procesowi kompilacji przy pomocy Process Monitor'a. Ponieważ aplikacja w trybie domyślnym wyświetla ogromną ilość danych (setki tysiące wierszy) postanowiłem skupić się tylko na wpisach dotyczących jednego z plików, dla których kompilator zgłaszał błąd. Po włączeniu filtrowania uzyskałem taki wynik:
Na niebiesko oznaczyłem wiersz, w którym widać, że kompilator nie uzyskał dostępu do pliku z powodu błędu SHARING VIOLATION. Błąd ten oznacza, że plik był w tym momencie w użyciu. Ponieważ problematyczny plik Html był generowany w całości przez mój kod mogłem założyć, że błąd tkwi po mojej stronie. Jak się okazało popełniłem akademicki błąd i nie zamykałem strumienia do pliku (do tej pory biję się w pierś). Oczywiście konstrukcja using rozwiązała problem.
Cały czas pozostaje jednak pytanie czemu błąd pojawiał się tylko dla określonych plików. Strumień nie był przecież zamykany dla każdego dynamicznie wygenerowanego pliku Html. W tym przypadku odpowiedź też nie jest skomplikowana - musiał zadziałać mechanizm automatycznego zwalniania pamięci garbage collector.
Cały czas pozostaje jednak pytanie czemu błąd pojawiał się tylko dla określonych plików. Strumień nie był przecież zamykany dla każdego dynamicznie wygenerowanego pliku Html. W tym przypadku odpowiedź też nie jest skomplikowana - musiał zadziałać mechanizm automatycznego zwalniania pamięci garbage collector.
0 comments:
Post a Comment