Home All Groups Group Topic Archive Search About

Threads do not Terminate!

Author
29 Jun 2006 1:24 PM
R. Nachtsturm
Hi,

i have the problem that when i create a low priority background thread,
start it, and wait for it to finish that it does not seem to terminate even
after it is finished..

if i use performance monitoring to watch the actual thread count then it
never goes down.. everytime i create a thread it goes up by one.. even if i
abort the thread and set the thread object = nothing it still doesn't decrease

i am now having a problem with one applpication that creates and closes 2
threads every hour that it starts using 50% cpu after a few days even while
doing absolutly NOTHING.. i think that this might be due to the thread
overhead of a few thousend unfinished threads...

so how to i properly terminate a worker thread?!
..abort doesn't work
=nothing doesn't work
knowing the thread is supposed to be finished (has finished all tasks,
thread start sub has exited! but yet it sill doesn't close!!!!

here is the a sample code to show what i mean:
(simple console program, in an infinite loop, it creates a new thread every
3 seconds.. every second it shows the number of threads it is using)

Module Module1
    Sub Main()
        Dim oDiag As New System.Diagnostics.PerformanceCounter(".NET CLR
LocksAndThreads", "# of current recognized threads",
IO.Path.GetFileNameWithoutExtension(System.Diagnostics.Process.GetCurrentProcess.MainModule.FileName), My.Computer.Name)
        Dim iCount As Integer = 1, oThread As Threading.Thread = Nothing
        Do
            Console.WriteLine("Thread Count: " & oDiag.RawValue)
            iCount += 1
            If (iCount > 3) Then
                iCount = 1
                If oThread IsNot Nothing Then oThread.Abort()
                oThread = New Threading.Thread(AddressOf ThreadStart)
                oThread.Priority = Threading.ThreadPriority.BelowNormal
                oThread.IsBackground = True
                oThread.Start()
                'Threading.ThreadPool.QueueUserWorkItem(AddressOf ThreadStart)
            End If
            Threading.Thread.Sleep(1000)
        Loop
    End Sub
    Private Sub ThreadStart(Optional ByVal oState As Object = Nothing)
        Console.WriteLine("Thread Started!")
        For i As Integer = 1 To 1000
            Dim a As Double = (i * 3.73)
            a = i
        Next
        Console.WriteLine("Thread Finished! (Should Terminate, Right?)")
    End Sub
End Module

please, any help would be greatly appriciated!

Author
29 Jun 2006 1:40 PM
R. Nachtsturm
A few more things i found out:

it only does this in .Net 2.0 (2005)

i modified the same program to work with .Net 1.1 (2003)  (see source here
below)

when a thread finishes in .Net 1.1, it FINISHES!.. in .Net 2.0 it does
something ELSE, i mean other then finishing... WHY?! A Thread doesn't use
iDisposable, i can't make sure it 'disposed' of.. i can't make sure it
stops...

is this a bug with .Net 2.0?... or did they change the thread handing in
such a way that whatever i have been doing (and was working) is now deemed to
be horribly worng?

here the same code fixed up for .Net 1.1:

Module Module1
    Sub Main()
        Dim oDiag As New System.Diagnostics.PerformanceCounter(".NET CLR
LocksAndThreads", "# of current recognized threads",
IO.Path.GetFileNameWithoutExtension(System.Diagnostics.Process.GetCurrentProcess.MainModule.FileName), System.Net.Dns.GetHostName())
        Dim iCount As Integer = 1, oThread As Threading.Thread = Nothing
        Do
            Console.WriteLine("Thread Count: " & oDiag.RawValue)
            iCount += 1
            If (iCount > 3) Then
                iCount = 1
                If Not oThread Is Nothing Then oThread.Abort()
                oThread = New Threading.Thread(AddressOf ThreadStart)
                oThread.Priority = Threading.ThreadPriority.BelowNormal
                oThread.IsBackground = True
                oThread.Start()
            End If
            Threading.Thread.Sleep(1000)
        Loop
    End Sub
    Private Sub ThreadStart()
        Console.WriteLine("Thread Started!")
        For i As Integer = 1 To 1000
            Dim a As Double = (i * 3.73)
            a = i
        Next
        Console.WriteLine("Thread Finished! (Should Terminate, Right?)")
    End Sub
End Module
Author
29 Jun 2006 5:11 PM
Jared Parsons [MSFT]
Hello R. Nachtsturm,

> Hi,
>
> i have the problem that when i create a low priority background
> thread, start it, and wait for it to finish that it does not seem to
> terminate even after it is finished..

I think the problem you're running into here is the difference between native
and managed threads.  Whenever you have a thread in VB (or any managed language
for that matter) it is backed by a real operating system thread.  There is
not a strict 1 to 1 relationship here and the CLR often keeps a lot of native
threads lying around to make managed threads faster. 

> Console.WriteLine("Thread Count: " & oDiag.RawValue)

I had to alter your sample slightly here because I wasn't able to create
the appropriate performance counter.  I changed the above line to the following
(pretty much equivalent).

> Console.WriteLine("Thread Count: " & Process.GetCurrentProcess().Threads.Count)

For me in constantly prints out that there are 11 threads in the process.
This is actually the count of native operating system threads.  However
the managed threads are finishing.  You can verify this by adding a oThread.Join()
immediately after oThread.Start().  It still says 11 threads but it is able
to join successfully.

--
Jared Parsons [MSFT]
jared***@online.microsoft.com
All opinions are my own. All content is provided "AS IS" with no warranties,
and confers no rights.