call a function a LOT of times

PutterPlace

Active member
Joined
Feb 18, 2008
Messages
37
Programming Experience
1-3
I am currently working on the concept of a new project I'm going to work on. What I want to do is basically call a function a LOT of times....one after the other (an HttpWebRequest & HttpWebResponse). This is basically what's going to happen:

A listbox will contain a few hundred number sequences...

VB.NET:
987234
928324
124809
235908
719823
234799
235987
209834
839228
etc...

I have already worked out the code to pull a number from the list box and then delete it. Each number is be pulled one at a time, and then sent with a URL in an HttpWebRequest:

VB.NET:
http://www.someURL.com/something.php?id=[NUMBER]

[NUMBER] will, of course, be replaced with the number that was just pulled from the list box. After this I will of course get the HttpWebResponse, then check if a specific string exists in the response. If so, write a result to another list box:

[NUMBER] - OK

If that string doesn't exist, then write a failed result to the list box:

[NUMBER] - FAILED

Then move on to the next number and do the same thing. I have already written a code that does this, but what I want is basically some kind of function or something to this more quickly and efficiently than doing it one at a time. I've heard of using threads, but am not very skilled with doing so. Any help would be greatly appreciated.
 
Please provide thread titles that describe the issue in future. Titles like "Quick Question - VB.NET" don't really help anyone.

The best solution to your problem would be to use the thread pool. Basically, you give the system instructions on what to do and let it manage when to do it. That will ensure that you don't have too many simultaneous work items, but that you do have enough to speed up the overall process. In basic form it would look something like this:
VB.NET:
Private Sub ProcessAllItems()
    Dim itemCount As Integer = Me.ListBox1.Items.Count

    For count As Integer = 1 To itemCount Step 1
        Threading.ThreadPool.QueueUserWorkItem(New Threading.WaitCallback(AddressOf ProcessItem), _
                                               Me.ListBox1.Items(0))
        Me.ListBox1.Items.RemoveAt(0)
    Next count
End Sub

Private Sub ProcessItem(ByVal data As Object)
    'Process data here.
End Sub
There are numerous ways you could adjust that. I've constructed the loop the way I did so that you can work from top to bottom, deleting items as you go, without affecting, or being affected by, new items being added to the end of the list.
 
Note that the ProcessItem method will be executed in a background thread. It may be executed several times simultaneously, depending on the number of items in the list and the number of available thread pool threads. At the end of ProcessItem method, if you want to update your UI you will need to use delegation. I won't address that topic specifically until you get there but, if you want to do some reading on the subject, try this.
 
OK. Looks pretty good, and very self-explantory about what is going on. Since I'm not at my workstation, I can't implement it yet, but in the meantime I'll do some reading on the link you posted. I'll also read more about pool threading.

While I'm thinking of it...within the ItemProcess procedure could I write the "OK" or "FAILED" statement to a new list box?
 
With WebClient you can do most of WebRequest functionality, only easier. It also have async methods that callback on caller thread context (it has same feature as BackgroundWorker). Using async methods of Socket related classes also usually give better performance than client/pool threading.
VB.NET:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim url As String = "http://WebSite/page.aspx?id="
    For i As Integer = 0 To 100
        Dim c As New Net.WebClient
        AddHandler c.DownloadStringCompleted, AddressOf c_DownloadStringCompleted
        c.DownloadStringAsync(New Uri(url & i.ToString), i.ToString)
    Next
End Sub

Private Sub c_DownloadStringCompleted(ByVal sender As Object, ByVal e As Net.DownloadStringCompletedEventArgs)
    Dim c As Net.WebClient = sender
    RemoveHandler c.DownloadStringCompleted, AddressOf c_DownloadStringCompleted
    c.Dispose()
    If e.Error Is Nothing Then
        Dim s As String = e.Result
        Me.ListBox1.Items.Add(String.Format("{0} - {1}", e.UserState, s))
    End If
End Sub
 
It's a good idea to clean up resources too, I forgot this in the haste, but have added RemoveHandler + Dispose in completed event code now.
 
The first thing I was going to do was to try jmcilhinney's suggestion first. I have one question for now...how do I reference the item taken from "Me.ListBox1.Items(0)". I will need the value of that when I'm processing the item.

Thanks again for all of your help.
 
The first thing I was going to do was to try jmcilhinney's suggestion first. I have one question for now...how do I reference the item taken from "Me.ListBox1.Items(0)". I will need the value of that when I'm processing the item.

Thanks again for all of your help.
I'll give you one guess.
VB.NET:
Private Sub ProcessItem(ByVal [COLOR="Red"]data[/COLOR] As Object)
    [COLOR="Red"]'Process data here.[/COLOR]
End Sub
 
Back
Top