List od Marcina Sikorskiego (19 XI 2007)
----------------------------------------

Wielu programistów korzystających z klasy TThread w VCL (Delphi lub Borland C++Builder) popełnia ten sam błąd polegający na zwalnianiu obiektów wykorzystywanych w osobnym wątku w destruktorze klasy podczas gdy nie jest oczywiste, że metoda Execute w tym czasie zakończyła już swoje działanie.
Programiści, pisząc swoją klasę wątku dziedziczącą z TThread tworzą swój destruktor wirtualny, w którym usuwają wszystkie utworzone w konstruktorze obiekty. Jest to oczywiście poprawne, ale nie dla wątków. Kod własnego destruktora wątku wykonywany jest w kontekście wątku, który wywołuje usunięcie obiektu, zanim wątek ten zakończy swoje działanie. Warto jednak wiedzieć, że destruktor nie sprawdza w żaden sposób, czy instrukcje metody Execute zostały już wykonane do końca (jej działanie nie jest zsychronizowane z wątkiem, który usuwa nasz wątek) - osobny wątek może nadal działać, a tym samym odwoływać się do usuniętych w destruktorze obiektów. Metoda Execute wygląda zwykle następująco:
	void TMojWatek::Execute()
	{
		while (!Terminated)
		{
			instrukcja1
			instrukcja2
			instrukcja3
			instrukcja4
			instrukcja5
			odwolanie do zasobu
			instrukcja6
		}
		instrukcja7
	}
	
Załóżmy, że destruktor zostanie wykonany w trakcie działania instrukcji od 1 do 5. Wówczas odwołanie do zasobów stworzonych na potrzeby wątku zakończy się błędem powodującym zakończenie działania programu (komunikat "Abnormal program termination").
Łatwo to sprawdzić wstawiając breakpoint w linii "instrukcja7" oraz w pierwszej linii destruktora ~TMojWatek, a okaże się która linia wykona się pierwsza.
Jest to spowodowane tym, iż zgodnie z zasadą dziedziczenia najpierw wywołuje się nasz destruktor a dopiero potem destruktor ~TThread, który zajmuje się zatrzymaniem wątku i oczekiwaniem na jego zakończenie:
Jego kod w przybliżeniu wygląda tak:
	~TThread()
	{
		this->Terminate();
		this->WaitFor();
		Free();
	}
	
Funkcja Terminate() nie robi nic innego jak tylko ustawia Terminated na true. Zadaniem wątku (metoda Execute) jest cykliczne sprawdzanie tej zmiennej i ewentualne zakończenie swojej pracy - i zwolnienie swoich zasobów.
Opisany powyżej problem można rozwiązać na kilka sposobów:
Z poważaniem
Marcin Sikorski