11/11/2014

Domeny aplikacyjne i wątki

Home

Jakiś czas temu odpowiedziałem na pytanie na stackoverflow.com dotyczące kończenia pracy wątków z zewnętrznej biblioteki w sytuacji kiedy powinny już zakończyć pracę, a jednak tego nie zrobiły. Moja odpowiedź została co prawda skrytykowana, zresztą słusznie, ale dzięki temu dowiedziałem się rzeczy, która mi wcześniej umknęła.

W mojej odpowiedzi zasugerowałem, że skoro z jakiegoś powodu musimy użyć zewnętrznej biblioteki i ona nie działa to ja bym ją załadował do oddzielnej domeny aplikacyjnej i w tej nowej domenie uruchomił też obliczenia (wątki). Taką domeną można natomiast w dowolnym momencie "odładować" przy pomocy AppDomain.Unload. Napisałem nawet przykład pokazujący, że to działa. W czym więc problem?

Otóż wywołanie AppDomain.Unload może się nie powieść i zostanie wtedy rzucony wyjątku CannotUnloadAppDomainException. Powodów mogą być trzy, ale nas interesuje jeden. Kiedy wołamy AppDomain.Unload i wewnątrz domeny są aktywne jakieś wątki to AppDomain.Unload spróbuje je ubić przy pomocy metody Thread.Abort. Jeśli się uda to ok, ale Thread.Abort może nie być w stanie ubić wątku i wtedy zostanie wygenerowany wzmiankowany powyżej wyjątek.

Kiedy Thread.Abort nie zadziała? Dokumentacja wspomina o dwóch przypadkach.
  • Kiedy wątek wykonuje kod niezarządzany.
  • Kiedy wątek wykonuje właśnie kod wewnątrz bloku finally. To można bardzo łatwo symulować przez umieszczenie wywołania Thread.Sleep(100000) wewnątrz bloku finally.

08/11/2014

Jako programista przyzwyczaiłem się do...

Home

Jakiś czas temu rozmawiałem z kolegą z branży i w pewnym momencie powiedział on zdanie, które utkwiło mi w pamięci. Parafrazując stwierdził, że:

"Jako programista przyzwyczaiłem się do tego, że się ze mną rozmawia."

Powiedział to w kontekście pracy w firmie, dla kogoś. Chodziło o to, że nawet jeśli coś mu się nie podobało, ale musiał to zrobić bo ktoś podjął taką decyzję, to nie bolało tak bardzo jeśli ktoś z nim wcześniej o tym porozmawiał. Mam tutaj na myśli zarówno sprawy techniczne co nasuwa się samo, ale również te "miękkie" na przykład związane z organizacją pracy.

Jak się nad tym chwilę zastanowiłem to stwierdziłem, że z pewnymi wyjątkami mam podobne doświadczenie i w sumie takie podejście wydało mi się oczywiste. Pytanie czy tak jest wszędzie? Może po prostu mieliśmy szczęście. Czy macie podobne wrażenia, a może wprost przeciwnie?

01/11/2014

Własne komendy w menu kontekstowym Windows'a

Home

Kiedy napiszę jakieś narzędzie to często chcę mieć do niego łatwy dostęp z poziomu menu kontekstowego Windows'a. Już od dłuższego czasu robię to przez dodanie odpowiednich wpisów do rejestru systemowego. W ogólności grzebanie w rejestrze nie jest bardzo przyjemne i istnieje ryzyko, że się coś popsuje. Dlatego też korzystam z następujących wypróbowanych wzorców.

Jeśli polecenie ma być dostępne dla wszystkich plików
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\*\Shell\COMMAND_NAME]
[HKEY_CLASSES_ROOT\*\Shell\COMMAND_NAME\command]
@="COMMAND"
Jeśli polecenie ma być dostępne dla określonych plików
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\.EXTENSION\Shell\COMMAND_NAME]
[HKEY_CLASSES_ROOT\.EXTENSION\Shell\COMMAND_NAME\command]
@="COMMAND"
Jeśli polecenie ma być dostępne dla katalogów
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\Directory\Shell\COMMAND_NAME]
[HKEY_CLASSES_ROOT\Directory\Shell\COMMAND_NAME\command]
@="COMMAND"

[HKEY_CLASSES_ROOT\Directory\Background\Shell\COMMAND_NAME]
[HKEY_CLASSES_ROOT\Directory\Background\Shell\COMMAND_NAME\command]
@="COMMAND"
W powyższych wzorcach COMMAND_NAME oznacza nazwę opcji jaka pojawi się w menu kontekstowym np.: Shred, EXTENSION to rozszerzenie pliku np.: txt i w końcu COMMAND to skrypt/polecenie jakie ma zostać wykonane po wybraniu przez użytkownika określonej opcji z menu kontekstowego np.: T:\\bin\\shred -n 10 -v -z \"%1\". Zwróćcie uwagę, że przy podawaniu ścieżki stosuję podwójny ukośnik tj. \\ oraz, że cudzysłów wewnątrz polecenia jest poprzedzony ukośnikiem tj. \". Na koniec uzupełnione wzorce należy zapisać w pliku z rozszerzeniem *.reg i przez podwójne kliknięcie na takim pliku dodać go do rejestru. Zmiany będą widoczne natychmiast.

29/10/2014

Co wyróżnia bardzo dobrego programistę (2)?

Home

Pewnie słyszeliście o strumieniach (ang. stream) w .NET. O tym, że się je otwiera, a po użyciu zamyka. Zresztą w innych technologiach jest podobnie. Sprawa stara jak świat i wydawałoby się, że każdy o tym wie. Ja w każdym razie z definicji tak robię.

Dziwi mnie więc, że po tylu latach istnienia .NET ciągle pojawiają się pytanie z tym związane, jak na przykład to na stackoverflow.com. Dziwi mnie również, że przy okazji tego rodzaju pytań często pojawiają się najróżniejsze koncepcje / pomysły / odpowiedzi i to od użytkowników, którzy wcale nie są początkujący. Tymczasem wystarczy wrócić do podstaw, aby rozwiązać problem.

A może jest tak, że kiedy na co dzień pracujemy z skomplikowanymi algorytmami / trudnymi problemami biznesowymi / strukturami danych (niepotrzebne skreślić) to w pewnym momencie tracimy perspektywę i każdy napotkany problem od razu wydaje się nam skomplikowany.

Kolejny czynnik powodujący tą utratę perspektywy to chyba również mnogość różnych technologii i bibliotek, jakie są u obecnie używane. Ta biblioteka do tego, tamta ułatwia to, ta automatyzuje tamto itd. W ten sposób przyzwyczajamy się do tego, że wiele rzeczy coś robi za nas i my nie wnikamy w szczegóły i równocześnie zapominamy również o podstawach.

Nie mówię, że nie należy używać bibliotek, framework'ów czyli ułatwiać sobie pracy, ale bardzo dobry programista powinien również wiedzieć co, się za tym wszystkim kryje i nie zapominać o podstawach.

20/10/2014

Z rozmów o pracę

Home

Nie wiem dlaczego, ale ostatnio wzięło mnie na refleksje. Siedzę, popijam sobie herbatę i tak ni z gruszki ni z pietruszki przypomniała mi się dawna rozmowa o pracę. Rozmawiałem z dwoma menadżerami, ale takimi z wiedzą techniczną, co to nie zmieniają szybko tematu, jak przechodzisz na tematy techniczne.

Rozmawialiśmy dość długo i w głowie utknęła mi jedna rzecz, jaką powiedzieli. Parafrazując, zgodnie stwierdzili, że ciężko znaleźć programistę, który nie byłby code monkey. Przy czym przez code monkey rozumieli trochę coś innego niż ja w tamtym momencie. Ja pod tym terminem rozumiałem osobę słabo radząca sobie z programowaniem, umiejąca napisać coś pod dyktando, ale nie dużo więcej. Dla nich jednak code monkey mógł być nawet bardzo dobry technicznie programista, doskonale radzący sobie z zadaniami, samodzielny... lecz z jednym bardzo istotnym z ich menadżerskiego punktu widzenia "ale". To jest nie umiejący lub słabo radzący sobie z komunikacją, w szczególności z biznesem, ludźmi nietechnicznymi, taki nieumiejący postawić się w roli użytkownika końcowego.

Z pewnością my programiści nie jesteśmy mistrzami komunikacji i Ci, którzy posiadają obok wiedzy technicznej umiejętności miękkie mogą się łatwo wyróżnić. Zastanawiam się jednak czy rzeczywiście większość z nas to geeki, którzy nie widzą nic poza kodem. Co myślicie?