Counting Threads

How do you count running Threads?

This technique won’t be accurate. For example, how many running threads do you expect to see in the following example? 3 (main thread + 2 threads started by timer)? No! You get 5 or 7 (or maybe even more) based on how much time has elapsed from the start. And I guess there will be other cases where your suggested technique won’t be accurate.

Public Sub ProgramStarted()
	a.Start()
	b.Start()
End Sub

Dim WithEvents a, b As New Timer(5000)
Dim t1, t2 As Thread
Private Sub a_Tick(timer As Timer) Handles a.Tick
	If t1 IsNot Nothing AndAlso t1.IsAlive Then t1.Abort()
	t1 = New Thread(Sub()
						For i = 1 To 5000
							Debug.Print("1: " & i.ToString())
						Next
					End Sub)
	t1.Start()
End Sub

Private Sub b_Tick(timer As Timer) Handles b.Tick
	If t2 IsNot Nothing AndAlso t2.IsAlive Then t2.Abort()
	t2 = New Thread(Sub()
						For i = 1 To 5000
							Debug.Print("2: " & i.ToString())
						Next
					End Sub)
	t2.Start()
End Sub

Also, you have mentioned “thread safe global var”, are you referring to atomic operations? If so, what’s the point of those if there is no real multithreading in NETMF? Only one single thread can run at a time.

[quote]Also, you have mentioned “thread safe global var”, are you referring to atomic operations? If so, what’s the Also, you have mentioned “thread safe global var”, are you referring to atomic operations? If so, what’s the point of those if there is no real multithreading in NETMF? Only one single thread can run at a time.
[/quote]

Bzzzzzzzzz

MF implements a 20ms time slice when multiple threads are CPU ready. A running thread can get suspended at any time, and another thread can run. that is why locking and mutexs are implemented I’m MF.

one of the best features of MF is that it supports true multi threading!

@ Mike
When I say there is “no real multithreading”, I mean that parallel execution is not possible. At one point in time [em]only one thread[/em] will be doing something, while all the other threads will be waiting.

I did some reading and some testing. One thing I was wrong about was that something like this [em]a += 1[/em] is not and indivisible instruction.
I have tried a sample code suggested by MS to test thread-safe way to increment and decrement an integer value. But strange thing happens when I set to create more instances of CountClass (e. g. 90k instead of 10k). I get “SafeCountInstances: -4” instead of expected zero value. Is Interlocked class not 100% thread-safe?

Partial Public Class Program

	Dim WithEvents MyTimer As New Timer(3000, Timer.BehaviorType.RunOnce)

	Public Sub ProgramStarted()
		MyTimer.Start()
		Debug.Print("Program Started")
	End Sub

	Private Sub MyTimer_Tick(timer As Timer) Handles MyTimer.Tick
		Dim thread1 As New Thread(AddressOf ThreadMethod)
		Dim thread2 As New Thread(AddressOf ThreadMethod)
		thread1.Start()
		thread2.Start()
		thread1.Join()
		thread2.Join()

		' Have the garbage collector run the finalizer for each 
		' instance of CountClass and wait for it to finish.
		Debug.GC(True)
		GC.WaitForPendingFinalizers()

		Debug.Print("UnsafeInstanceCount: " & CountClass.UnsafeInstanceCount.ToString() & _
			vbCrLf & "SafeCountInstances: " & CountClass.SafeInstanceCount.ToString())
	End Sub

	Shared Sub ThreadMethod()
		Dim cClass As CountClass

		For i As Integer = 1 To 1000
			cClass = New CountClass()
		Next
	End Sub
End Class

Public Class CountClass
	Shared unsafeCount As Integer = 0
	Shared safeCount As Integer = 0

	Shared ReadOnly Property UnsafeInstanceCount As Integer
		Get
			Return unsafeCount
		End Get
	End Property

	Shared ReadOnly Property SafeInstanceCount As Integer
		Get
			Return safeCount
		End Get
	End Property

	Sub New()
		unsafeCount += 1
		Interlocked.Increment(safeCount)
	End Sub

	Protected Overrides Sub Finalize()
		unsafeCount -= 1
		Interlocked.Decrement(safeCount)
		MyBase.Finalize()
	End Sub
End Class