tThreadA is the trivial thread. Executed, it increases both the tMyClass FLaunchedThreadsA and FActiveThreadsA counters by a value of 1, using a critical section. It then Sleeps a random number of millisecs and goes off. Once it terminates, it fires the OnTerminate event which decreases tMyClass.FActiveThreadsA by one. It was there I was getting issues at.
That right here is your problem. One of the
tThreadA might be just started and increases
FActiveThreadsA in a critical section, but at the same time another thread might terminate and thus (in the main thread) decrease
FActiveThreadsA without any critical section. That is why using a critical section helps for you.
What you can also do is move the incrementation into a synchronized method as well (this way all modifications would be in the main thread).
Though in my opinion you should - instead of using a critical section for this - use the
InterlockedIncrement and
InterlockedDecrement functions. These use locking operations of the CPU (or the operating system if the CPU has no such support) to modify the value and are thread safe.