Results 1 to 6 of 6

Thread: Threading and Loops

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Feb 2000
    Location
    Dayton, OH USA
    Posts
    119

    Unhappy Threading and Loops

    I need to loop through a data reader and spawn a seperate thread for each item within the set. You can see my code below, but it does not appear to work as I thought. This application is running as windows service and this block of code executes via a timer. Any help or ideas would be GREATLY appreciated...


    Dim oDataReader As SqlDataReader
    Dim BootClass As New BootClass()

    Try
    If SQLCheck() Then
    Dim oCmd As New SqlCommand("BootGet", SQLConnObj)

    oDataReader = oCmd.ExecuteReader()

    While oDataReader.Read()
    Dim bootThread As New Thread(AddressOf BootClass.Reboot)

    BootClass.Server = oDataReader("Server")
    BootClass.Key = oDataReader("PKey")
    BootClass.Notify = oDataReader("Notify")

    bootThread.IsBackground = True
    bootThread.Name = "thd_" & Rnd()

    bootThread.Start()

    End While

    oDataReader.Close()
    Catch ex as exception
    'Do nothing in example
    End try

  2. #2
    PowerPoster hellswraith's Avatar
    Join Date
    Jul 2002
    Location
    Washington St.
    Posts
    2,464
    Try this:
    VB Code:
    1. Dim oDataReader As SqlDataReader
    2. Dim iCounter As Integer  'For naming the threads
    3.  
    4. 'Start the counter at zero
    5. iCounter = 0
    6.  
    7. Try
    8.    If SQLCheck() Then
    9.       Dim oCmd As New SqlCommand("BootGet", SQLConnObj)
    10.  
    11.       oDataReader = oCmd.ExecuteReader()
    12.  
    13.       While oDataReader.Read()
    14.          'Create a new instance of your bootclass for each thread.
    15.          'You don't want to share the same object on each thread.
    16.          Dim myBootClass As New BootClass()
    17.          Dim bootThread As New Thread(AddressOf myBootClass.Reboot)
    18.  
    19.          myBootClass.Server = oDataReader("Server")
    20.          myBootClass.Key = oDataReader("PKey")
    21.          myBootClass.Notify = oDataReader("Notify")
    22.  
    23.          bootThread.IsBackground = True
    24.          bootThread.Name = "thd_" & iCounter.ToString() 'Use the counter to name it uniquely
    25.  
    26.          bootThread.Start()
    27.  
    28.          'Increase counter by one
    29.          iCounter++
    30.       End While
    31.  
    32.       oDataReader.Close()
    33. Catch ex as exception
    34.       'Do nothing in example
    35. End try

  3. #3

    Thread Starter
    Lively Member
    Join Date
    Feb 2000
    Location
    Dayton, OH USA
    Posts
    119
    Looks like I was going down the correct path, but just not close enough. So far my testing looks good and I am seeing none of the problems that I was before. THANK YOU SOOOOO MUCH, hellswraith!

  4. #4

    Thread Starter
    Lively Member
    Join Date
    Feb 2000
    Location
    Dayton, OH USA
    Posts
    119
    I apparently spoke to soon. For the most part I am seeing the same issue as before. Essentially, all this app does is read server names, times, etc from a SQL db and reboot servers. The service checks the db every 10 seconds for new servers. Once it finds one or many it loops through the dataset and spawns a seperate thread to manage each reboot. The problem comes when I throw a server name that does not exist. My code knows how to account for this, tries 5 times, then exits the sub-routine. If I give it two servers that do not exist it works fine. If I give it 3 servers that do not exist, it loops through each one, creates a thread for each then does nothing. The only thing it does do is create more and more threads and consumes more and more memory until it blows up. I know that these threads are not coming from my loop because I write them to a log file. So, the big question is, where are these extraneous threads being created from and why does it handle 2 but not 3. Here is some more code:
    VB Code:
    1. Protected Overrides Sub OnStart(ByVal args() As String)
    2.  
    3.         Dim Timer As New Timers.Timer()
    4.  
    5.         OpenLog()
    6.  
    7.         AddLog("-----------------------------------------")
    8.         AddLog(Me.ServiceName & " Started [" & GetVersion() & "]")
    9.         AddLog("Log Open")
    10.         AddLog("Database Open : " & OpenSQL())
    11.  
    12.         AddHandler Timer.Elapsed, AddressOf OnTimedEvent
    13.         Timer.Interval = (GetDataFromXML("/config/chkinterval") * 1000)
    14.         Timer.Start()
    15.  
    16.         AddLog("Timer Started : " & (Timer.Interval / 1000) & " second loop interval")
    17.     End Sub
    18.  
    19. Private Sub OnTimedEvent(ByVal source As Object, ByVal e As Timers.ElapsedEventArgs)
    20.  
    21.         Dim oDataReader As SqlDataReader
    22.         Dim iCounter As Integer
    23.  
    24.         iCounter = 0
    25.  
    26.         Try
    27.             If SQLCheck() Then
    28.                 Dim oCmd As New SqlCommand("BootGet", SQLConnObj)
    29.  
    30.                 oDataReader = oCmd.ExecuteReader()
    31.  
    32.                 While oDataReader.Read()
    33.                     Dim myBootClass As New BootClass()
    34.                     Dim bootThread As New Thread(AddressOf myBootClass.Reboot)
    35.  
    36.                     myBootClass.Server = oDataReader("Server")
    37.                     myBootClass.Key = oDataReader("PKey")
    38.                     myBootClass.Notify = oDataReader("Notify")
    39.  
    40.                     bootThread.IsBackground = True
    41.                     bootThread.Name = "thd_" & iCounter.ToString()
    42.  
    43.                     bootThread.Start()
    44.  
    45.                     iCounter += 1
    46.  
    47.                     'ThreadPool.QueueUserWorkItem(AddressOf BootClass.Reboot, "Running") ', oDataReader("Server") & "|" & oDataReader("PKey") & "|" & oDataReader("Notify"))
    48.                     AddLog("Reboot thread initialized [" & oDataReader("Server") & "-" & bootThread.Name & "]")
    49.                 End While
    50.  
    51.                 oDataReader.Close()
    52.  
    53.                 TimeErrCnt = 0
    54.             End If
    55.         Catch ex As Exception
    56.  
    57.             If oDataReader.IsClosed = False Then
    58.                 oDataReader.Close()
    59.             End If
    60.  
    61.             TimeErrCnt += 1
    62.  
    63.             If TimeErrCnt >= 5 Then
    64.                 AddLog("Timer Error : " & TimeErrCnt & " : Critical error level exceeded, service shutting down.  Error Detail: BootManager:OnTimedEvent")
    65.                 SendNotify(ex.Message, GetDataFromXML("/config/adminnotify"))
    66.                 End
    67.             End If
    68.  
    69.             Thread.CurrentThread.Sleep(10000)
    70.  
    71.             AddLog("Timer Error : " & TimeErrCnt & " : " & ex.Message & " Error Detail: BootManager:OnTimedEvent")
    72.         End Try
    73.  
    74.     End Sub
    75.  
    76. Public Class BootClass
    77.  
    78.     Public Server As String
    79.     Public Key As Integer
    80.     Public Notify As String
    81.  
    82.     Public Sub Reboot()
    83.  
    84.         Dim BootErrCnt As Integer = 1
    85.  
    86.         If SQLCheck() Then
    87.  
    88.             Dim Path As New ManagementPath()
    89.  
    90.             Path.Server = Server
    91.             Path.NamespacePath = "root\CIMV2"
    92.  
    93.             Dim Scope As New ManagementScope(Path)
    94.  
    95.             Scope.Options.Username = UserName
    96.             Scope.Options.Password = Password
    97.  
    98.             Scope.Options.Impersonation = ImpersonationLevel.Impersonate
    99.             Scope.Options.EnablePrivileges = True
    100.  
    101.             Do While BootErrCnt <= 5
    102.                 Try
    103.                     Scope.Connect()
    104.                     Exit Do
    105.                 Catch ex As Exception
    106.                     If BootErrCnt = 5 Then
    107.                         If SQLCheck() Then
    108.                             Dim oFCmd As New SqlCommand("BootLogInsert " & Key & ",'" & ex.Message & "(Error Count:" & BootErrCnt & " : Exiting thread)'", SQLConnObj)
    109.                             oFCmd.ExecuteNonQuery()
    110.                         End If
    111.  
    112.                         AddLog("Boot Error : " & Server & " : " & BootErrCnt & " : " & ex.Message & " : Exiting thread")
    113.  
    114.                         If Not Notify = "" Then
    115.                             SendNotify(Server & " reboot failure", Notify)
    116.                         End If
    117.  
    118.                         Exit Sub
    119.                     Else
    120.                         Thread.CurrentThread.Sleep(10000)
    121.  
    122.                         If SQLCheck() Then
    123.                             Dim oECmd As New SqlCommand("BootLogInsert " & Key & ",'" & ex.Message & "(Error Count:" & BootErrCnt & ")'", SQLConnObj)
    124.                             oECmd.ExecuteNonQuery()
    125.                         End If
    126.  
    127.                         AddLog("Boot Error : " & Server & " : " & BootErrCnt & " : " & ex.Message)
    128.  
    129.                         BootErrCnt += 1
    130.                     End If
    131.                 End Try
    132.             Loop
    133.  
    134.             Dim Query As New ObjectQuery("SELECT * FROM Win32_OperatingSystem")
    135.             Dim Searcher As New ManagementObjectSearcher(Scope, Query)
    136.             Dim myObject As New ManagementObject()
    137.             Dim InParams As ManagementBaseObject()
    138.  
    139.             For Each myObject In Searcher.Get
    140.                 myObject.Scope.Options.EnablePrivileges = True
    141.                 myObject.InvokeMethod("Reboot", InParams)
    142.             Next
    143.  
    144.             If SQLCheck() Then
    145.                 Dim oSCmd As New SqlCommand("BootLogInsert " & Key & ", 'Successfull'", SQLConnObj)
    146.                 oSCmd.ExecuteNonQuery()
    147.             End If
    148.  
    149.             AddLog("Reboot Success : " & Server)
    150.  
    151.             If Not Notify = "" Then
    152.                 SendNotify(Server & " successfully rebooted", Notify)
    153.             End If
    154.         End If
    155.     End Sub
    156.  
    157. End Class
    Last edited by VB-Mike; Jan 7th, 2003 at 07:49 AM.

  5. #5

    Thread Starter
    Lively Member
    Join Date
    Feb 2000
    Location
    Dayton, OH USA
    Posts
    119
    Ok, here is the other wierd thing. Put some output in the loop that calls the thread and the thread code itself:

    [1/7/2003 8:22:06 AM] - Thread initialized [TEST-thd_0]
    [1/7/2003 8:22:06 AM] - Thread initialized [ME-thd_1]
    [1/7/2003 8:22:06 AM] - Thread initialized [G-thd_2]

    [1/7/2003 8:22:06 AM] - Thread started [TEST - thd_0]
    [1/7/2003 8:22:06 AM] - Thread started [TEST - thd_0]
    [1/7/2003 8:22:06 AM] - Thread started [ME - thd_1]
    [1/7/2003 8:22:06 AM] - Thread started [TEST - thd_0]
    [1/7/2003 8:22:06 AM] - Thread started [ME - thd_1]
    [1/7/2003 8:22:06 AM] - Thread started [G - thd_2]

    The "thread initialized" comes from the loop and the thread call. The "thread started" comes from the actual thread class itself. Notice that TEST shows up 3 times, ME 2 times, and G one time. Cannot figure this out, specially when each thread was only called once.

  6. #6

    Thread Starter
    Lively Member
    Join Date
    Feb 2000
    Location
    Dayton, OH USA
    Posts
    119
    Ok, think I have it figured out. Looks as if I need to sleep the application thread for a moment within the loop. I believe the loop was moving to fast and not allowing enough time for the thread to get created....

    thread.currentthread.slee(500)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width