Looping Multithread will cause HIGH USAGE?

knockyo

Well-known member
Joined
Sep 20, 2006
Messages
78
Programming Experience
1-3
VB.NET:
Do While Not stopFlag
   pmCon.QueryMe("Select * from DELL_OPC_ADDRESS where processing <> 1 and Active=1 and OPCServer=" & OPCServerNo2Scan, DTOPCAddress)

   If DTOPCAddress.Rows.Count <> 0 Then
      For Each DR In DTOPCAddress.Rows
          If Not OPCFunc.ReadOPCTag(DR("Address"), tmpValue) Then
             Log(DR("LifterId"), "*OPCtriggerSMS - Error reading address (" & DR("Address") & ")!")
             Application.DoEvents()
             Continue For
          End If

          'Need to update RealTimeData so that this value can be reset. It is important for Address where OPC ResetValue='NO ACTION'
          If tmpValue <> cNULL(DR("RealTimeData")) Then
             pmCon.UpdateMe("Update DELL_OPC_ADDRESS set RealTimeData='" & tmpValue & "' where Address='" & DR("Address") & "'")
          End If


          If Not tmpValue Is Nothing Then
             Dim NeedTrigger As Boolean = False
             Select Case DR("triggerValue")
                Case "EMPTY"
                     If CStr(tmpValue).Trim = "" Then NeedTrigger = True
                Case "NONEMPTY"
                     If CStr(tmpValue).Trim <> "" Then NeedTrigger = True
                Case "TRUE", "FALSE"
                     Try
                        If CBool(tmpValue) = CBool(DR("triggerValue")) Then
                           NeedTrigger = True
                        End If
                     Catch ex As Exception

                     End Try
                Case "NONZERO"
                     If IsNumeric(tmpValue) Then
                        If CDbl(tmpValue) <> 0 Then NeedTrigger = True
                     End If
                Case "0", "1", "2"
                     If tmpValue = DR("triggerValue") Then NeedTrigger = True
             End Select

             'Check if the TriggerValue stays there forever (due to ResetValue='NO ACTION').
             If NeedTrigger And DR("ResetValue") = "NO ACTION" Then
                If tmpValue = DR("RealTimeData") Then NeedTrigger = False
             End If

             If NeedTrigger Then
                Dim NewThread As New clsThread
                NewThread.AssignValue(DR, tmpValue)
                Dim T As New System.Threading.Thread(AddressOf NewThread.InvokeMethod)
                T.Start()
             End If
          End If

          pmCon.UpdateMe("Update DELL_OPC_ADDRESS set processing=0 where processing=1 and LastUpdateDT <= '" & _
                Format(DateAdd(DateInterval.Minute, -1 * CDbl(MinB4ResetToFalse), Now), "dd-MMM-yyyy hh:mm:ss tt") & "'", True)

          Application.DoEvents()
          FlushMemory()
      Next
   End If

hi all,

Is that the multithread in the looping function will cause the scanning function slow?

This is because I have monitoring the time for scanning process.

When the program start to scan, it only take 4 sec. After that, it become slower from 4 sec to 7 sec. Besides that, I have monitoring the CPU & Memory Usage, it keep on increasing.

Until whole program lag and display out the Microsoft Dont Send report.

Any suggestion my coding above?
 
Here is my clsThread

VB.NET:
Imports System.Reflection
Public Class clsThread
    Private TheRecord As DataRow
    Private TheValue As Object
    Public ErrMsg As String
    Public Sub AssignValue(ByVal TheRcd As DataRow, ByVal Value As Object)
        TheRecord = TheRcd
        TheValue = Value
    End Sub


    Public Sub InvokeMethod()
        On Error GoTo e1
        Dim TC As Long
        TC = TheRecord("timeCounter")

        Dim pmCon1 As New pmServer.NET2006.SMS.Data.clsSQLDB(ConnStr)
        If pmCon1.UpdateMe("Update DELL_OPC_ADDRESS set processing=1, timeCounter=timeCounter+1, LastUpdateDT='" & _
            Format(Now, "dd-MMM-yyyy hh:mm:ss tt") & "' where Address='" & _
            TheRecord("Address") & "' and timeCounter=" & TC.ToString, False) <> 0 Then
            'System.Threading.Thread.CurrentThread.Abort()
            Exit Sub
        End If

        Log(TheRecord("LifterId"), "Detected " & TheRecord("Address") & "=" & TheRecord("triggervalue") & " (Trigger Value)!", False)
        Dim OPCFunc As New clsOPCFunctions

        Select Case TheRecord("ActionId").ToString.ToUpper
            Case "CHANGE STATE"
                Dim State As String = Nothing
                If IsDBNull(TheRecord("ActionPara1")) Then
                    Log(TheRecord("LifterId"), "Change State requires New State to be stated in ActionPara1!")
                End If
                'Do not need to read the OPC Tag for the new State. Straight away get the value from "ActionPara1"
                'OPCFunc.ReadOPCTag(TheRecord("ActionPara1"), State)
                State = TheRecord("ActionPara1")
                If Not State Is Nothing Then
                    If cNULL(TheRecord("RealTimeData")) <> TheValue Then
                        ChangeState(pmCon1, TheRecord("Address"), TheRecord("LifterId"), State, TheRecord("LineId"), TheValue)
                    End If
                End If

            Case "CHANGE MODE"
                If cNULL(TheRecord("RealTimeData")).ToUpper <> TheValue.ToString.ToUpper Then
                    ChangeMode(pmCon1, TheRecord("LineId"), TheRecord("LifterId"), TheRecord("ActionPara1"), TheRecord("ActionPara1"), TheValue)
                End If
            Case "RESET USAGE TO 0"
                ResetUsageTo0(pmCon1, TheRecord("LifterId"), TheRecord("ComponentId"), TheRecord("LineId"))
            Case "INCREMENT OUTPUT TOP", "INCREMENT OUTPUT BOTTOM", "INCREMENT OUTPUT RIGHT", "INCREMENT OUTPUT LEFT", _
                "INCREMENT OUTPUT LEVEL 1", "INCREMENT OUTPUT LEVEL 2", "INCREMENT OUTPUT LEVEL 3", _
                "INCREMENT OUTPUT LEVEL 4", "INCREMENT OUTPUT LEVEL 5", "INCREMENT OUTPUT LEVEL 6"
                Dim OutType As OutputType
                Select Case TheRecord("ActionId").ToString.ToUpper
                    Case "INCREMENT OUTPUT TOP"
                        OutType = OutputType.Top
                    Case "INCREMENT OUTPUT BOTTOM"
                        OutType = OutputType.Bottom
                    Case "INCREMENT OUTPUT RIGHT"
                        OutType = OutputType.Right
                    Case "INCREMENT OUTPUT LEFT"
                        OutType = OutputType.Left
                    Case "INCREMENT OUTPUT LEVEL 1"
                        OutType = OutputType.L1
                    Case "INCREMENT OUTPUT LEVEL 2"
                        OutType = OutputType.L2
                    Case "INCREMENT OUTPUT LEVEL 3"
                        OutType = OutputType.L3
                    Case "INCREMENT OUTPUT LEVEL 4"
                        OutType = OutputType.L4
                    Case "INCREMENT OUTPUT LEVEL 5"
                        OutType = OutputType.L5
                    Case "INCREMENT OUTPUT LEVEL 6"
                        OutType = OutputType.L6

                End Select
                If cNULL(TheRecord("ActionPara1")) = "" Then
                    IncrementOutput(pmCon1, TheRecord("LifterId"), TheRecord("LineId"), TheValue, OutType)
                Else
                    If Not IsNumeric(TheRecord("ActionPara1")) Then
                        IncrementOutput(pmCon1, TheRecord("LifterId"), TheRecord("LineId"), TheValue, OutType)
                    Else
                        'MsgBox("Address=" & TheRecord("Address") & ". TheValue=" & TheValue & ". ActionPara1=" & TheRecord("ActionPara1"))
                        IncrementOutput(pmCon1, TheRecord("LifterId"), TheRecord("LineId"), TheValue * CInt(TheRecord("ActionPara1")), OutType)
                    End If
                End If

            Case "INCREMENT USAGE"
                If cNULL(TheRecord("ActionPara1")) = "" Then
                    IncrementUsage(pmCon1, TheRecord("LifterId"), TheRecord("ComponentId"), TheValue, TheRecord("LineId"))
                Else
                    If Not IsNumeric(TheRecord("ActionPara1")) Then
                        IncrementUsage(pmCon1, TheRecord("LifterId"), TheRecord("ComponentId"), TheValue, TheRecord("LineId"))
                    Else
                        IncrementUsage(pmCon1, TheRecord("LifterId"), TheRecord("ComponentId"), TheValue * CInt(TheRecord("ActionPara1")), TheRecord("LineId"))
                    End If
                End If

            Case "SQL"
                If cNULL(TheRecord("ActionPara1")) <> "" Then
                    Dim SQL As String = TheRecord("ActionPara1")
                    SQL = SQL.Replace("#NOW#", Format(Now, "dd-MMM-yyyy HH:mm:ss tt"))
                    SQL = SQL.Replace("#VALUE#", TheValue.ToString)
                    Dim sqlStr() As String = SQL.Split(";;")
                    If pmCon1.UpdateBatchMe(sqlStr, True) <> 0 Then
                        Log(TheRecord("LifterId"), "Error executing SQL: " & SQL, True)
                    End If
                End If

            Case "ALARM"
                If cNULL(TheRecord("ComponentId")) = "" Then
                    LogAlarm(pmCon1, TheRecord("LineId"), TheRecord("LifterId"), TheValue)
                Else
                    LogAlarm(pmCon1, TheRecord("LineId"), TheRecord("LifterId"), TheValue, TheRecord("ComponentId"))
                End If
            Case "RECORD STATUS"
                If cNULL(TheRecord("ComponentId")) = "" Then
                    LogAlarm(pmCon1, TheRecord("LineId"), TheRecord("LifterId"), TheValue, , 0)
                Else
                    LogAlarm(pmCon1, TheRecord("LineId"), TheRecord("LifterId"), TheValue, TheRecord("ComponentId"), 0)
                End If
        End Select

        'Debug.Print(TheRecord("ActionId").ToString)


        'DTReset.Rows.Add(New Object() {"0"})
        'DTReset.Rows.Add(New Object() {"1"})
        'DTReset.Rows.Add(New Object() {"TRUE"})
        'DTReset.Rows.Add(New Object() {"FALSE"})
        'DTReset.Rows.Add(New Object() {"EMPTY"})
        'DTReset.Rows.Add(New Object() {"DECREMENT"})
        Select Case TheRecord("ResetValue")
            Case "DECREMENT"
                Dim currValue As Object = Nothing
                OPCFunc.ReadOPCTag(TheRecord("Address"), currValue, TheValue)
                OPCFunc.WriteOPCTag(TheRecord("Address"), currValue - TheValue)
            Case "EMPTY"
                OPCFunc.WriteOPCTag(TheRecord("Address"), "")
            Case "NO ACTION"
                'Do nothing
            Case Else
                OPCFunc.WriteOPCTag(TheRecord("Address"), TheRecord("ResetValue"))
        End Select


        ErrMsg = ""
        GoTo CleanUp
e1:
        If pmCon1.UpdateMe("Update DELL_OPC_ADDRESS set processing=0 where Address='" & _
            TheRecord("Address") & "'") <> 0 Then
            Log(TheRecord("LifterId"), "InvokeMethod.ErrorTrap-Error setting processing=0 for Address=" & TheRecord("Address") & "!")
        End If

        If ErrMsg <> "" Then
            Log(TheRecord("LifterId"), "+++InvokeMethod error: " & ErrMsg & ". " & Err.Description)
        Else
            Log(TheRecord("LifterId"), "+++InvokeMethod error: " & Err.Description)
        End If

        'InvokeMethod = False
CleanUp:

        If pmCon1.UpdateMe("Update DELL_OPC_ADDRESS set processing=0 where Address='" & _
            TheRecord("Address") & "'") <> 0 Then
            Log(TheRecord("LifterId"), "InvokeMethod.CleanUp-Error setting processing=0 for Address=" & TheRecord("Address") & "!")
        End If

        If Not pmCon1 Is Nothing Then pmCon1.Dispose()
        System.Threading.Thread.CurrentThread.Abort()
    End Sub
 
Some site are using delegates,

(1) may I know this function is should put at where?

(2) Is that will increase scanning performance and never cause high usage?

Please advice
 
Yeah, tight loop hammering a database that's a really great idea.. Think about some realtime thing like MSN messenger for a sec.. Do you think that every message you send is put ina db, and then some worker process of all your contacts repeatedly hammers the db hundreds of times per second to see if you sent a message?

Whatever happened to event driven architectures? This seems more like a networking problem than a database one
 
Back
Top