Solved

Is my VB.Net Threading Effecient

Posted on 2013-06-28
4
416 Views
Last Modified: 2013-06-29
I have a process that works

I get a list of data strings and for each datarow I send a command in a separate thread
to a web request
Each Web Request is kept open in a loop using While streamResponse.CanRead

I need to know if what I'm doing is the most efficient way or there is some way I can streamline this.

Basically, I want to know if there's anything I can move out of the thread sub and into something global.

Maybe the buffer?
Or request header?

Again...what I'm doing works.
First I have a summary of what is going on

Then I have the full code below in case you want to look at it


SUMMARY
=====================================================
Reading rows of strings

While row(i)  Read...
    Dim phoneWorkerThread As New Thread(AddressOf startPhoneMonitoring)
    phoneWorkerThread.Name = "Thread " + CStr(threadCounter) + " | [" + dataRowString + "]"  ' i being the loop counter.
    phoneWorkerThread.Start(sendRow)

End While


Private Sun startPhoneMonitoring(ByVal sendRow as String)

   'Kick off Web request with header info etc...
      'Blah...blah..blah...

      'The response object of 'HttpWebRequest' is assigned to a 'HttpWebResponse' variable.
      Using myHttpWebResponse As HttpWebResponse = CType(sendWebRequest.GetResponse(), HttpWebResponse)

      'Get the response stream
      Using streamResponse As Stream = myHttpWebResponse.GetResponseStream()

      'Next Line tricks into staying in Response Stream Loop
      While streamResponse.CanRead

      '      This keeps the stream open
      'Do some stuff...send each chunk of data to SQL Server

      End WHile

End Sub


DETAIL
=========================================================

 Private Sub getPhoneDataStream()
        Try
            'Som kind of messaging that process is initiated
            Me.Text = "HTTP POST STARTED"

            While returnedPhoneTable.Rows.Count > 0
                'Declare string to hold comma seperated phone string from datatable
                Dim dataRowString As String = ""

                'Declare var for data row in loaded data table
                Dim row = returnedPhoneTable.Rows(0)

                'Populate datarow string
                dataRowString = row("phoneList").ToString()

                'Declare string() to handle split by comma
                Dim sites As String() = dataRowString.Split(","c)
                Dim sendRow As String = ""

                'For each phone number build the command line
                'And group together all 7 numbers
                For Each s As String In sites
                    'Get command for this particular phone 
                    postData = getCommandString(s)

                    'Append to sendRow with line break to send all 7 phones to monitor at once
                    sendRow = sendRow + postData + vbCrLf
                Next


                Dim phoneWorkerThread As New Thread(AddressOf startPhoneMonitoring)
                phoneWorkerThread.Name = "Thread " + CStr(threadCounter) + " | [" + dataRowString + "]"  ' i being the loop counter.
                phoneWorkerThread.Start(sendRow)

                Debug.Write("Threads Starting: " + phoneWorkerThread.Name)
                'Declare and start individual thread for each loop

                'increase counter for next loop
                threadCounter = threadCounter + 1

                'Remove datarow just sent from datatable
                returnedPhoneTable.Rows.RemoveAt(0)

                'Reset SendRow string
                sendRow = ""

                'Since telephoy vendor needs about 1/2 second to process each phone...give plenty of time before next process start.
                System.Threading.Thread.Sleep(7000)
            End While
            'Dim thstre As String = threadList.ToString()
            'Dim dd As String = thstre
        Catch ex As Exception
            Debug.WriteLine("Error on thread " & CStr(threadCounter - 1) & vbCrLf & ex.Message.ToString)
        End Try
    End Sub



'Threaded web request
   Private Sub startPhoneMonitoring(ByVal sendRow As String)
        Try
            Dim sendWebRequest As HttpWebRequest = CType(WebRequest.Create(stUrl), HttpWebRequest)

            sendWebRequest.SendChunked = True
            sendWebRequest.Method = "POST"
            sendWebRequest.ContentType = "text/plain"
            sendWebRequest.KeepAlive = True
            sendWebRequest.UserAgent = "CometTest"
            sendWebRequest.ServicePoint.ConnectionLimit = 20
            sendWebRequest.Timeout = 43200
Resend:

            Dim encodedData As New ASCIIEncoding()
            Dim byteArray As Byte() = encodedData.GetBytes(sendRow)
            sendWebRequest.ContentLength = byteArray.Length

            Dim newStream As Stream = sendWebRequest.GetRequestStream()
            newStream.Write(byteArray, 0, byteArray.Length)
            newStream.Close()

            ' The response object of 'HttpWebRequest' is assigned to a 'HttpWebResponse' variable. 
            Using myHttpWebResponse As HttpWebResponse = CType(sendWebRequest.GetResponse(), HttpWebResponse)

                ' Displaying the contents of the page to the consoleor sending to web service/sql proc 
                Using streamResponse As Stream = myHttpWebResponse.GetResponseStream()

                    'Next Line tricks into staying in Response Stream Loop
                    While streamResponse.CanRead
                        'Declare StreamReader
                        Dim streamRead As New StreamReader(streamResponse)

                        'Declare as Set Buffer
                        Dim readBuff(5120) As [Char]

                        'Set counter in case 0 is returned
                        Dim count As Integer = streamRead.Read(readBuff, 0, 5120)

                        'Worker section.  Send to SQL
                        If count = 0 Then
                            'There are times when the initial send does not trigger a response. 
                            'If that happens, post again.  Only happens on first pass through
                            GoTo Resend
                        Else
                            'Set output data variable
                            Dim outputData As New [String](readBuff, 0, count)

                            'Send output to WCF
                            outputData = Replace(outputData, "<Result", "<timeStamp>" & Now().ToString("yyyy-MM-dd HH:mm:ss.fff") & "</timeStamp><Result")
                            'Dim b As Boolean = sendToWebService(outputData)

                            'Leave next two lines in for dev and reading what is being passed to WCF
                            Debug.WriteLine(ControlChars.Cr + outputData)
                        End If
                    End While
                End Using
            End Using
        Catch ex As Exception
            Debug.Write("Failed on this set: " & sendRow)
        End Try
    End Sub

Open in new window

0
Comment
Question by:lrbrister
  • 2
  • 2
4 Comments
 
LVL 83

Accepted Solution

by:
CodeCruiser earned 500 total points
ID: 39287214
Code looks fine to me. You can still make few tweaks like moving variable declaration out of while loop in getPhoneDataStream method but that would not make much difference.

You do not want to share things like buffers between threads as this can result in errors or in inconsistent data when multiple threads make changes to same object.

Have you looked at processor and memory consumption of the application?
0
 

Author Comment

by:lrbrister
ID: 39287262
Code Cruiser
Thanks
When this thing is running full bore, there's 12-13 threads and about 1000 XML chunks streaming in per minute to the wcf
Processor running at 8%
Memory at about 12-30 depending on load
0
 
LVL 83

Expert Comment

by:CodeCruiser
ID: 39287276
Looks good then.
0
 

Author Closing Comment

by:lrbrister
ID: 39287342
Thanks
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

After several hours of googling I could not gather any information on this topic. There are several ways of controlling the USB port connected to any storage device. The best example of that is by changing the registry value of "HKEY_LOCAL_MACHINE\S…
Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now