I'm running a site that imports product feeds from a variety of shops. These feeds can be quite huge, some are up to 1GB. Currently I import these by calling the import function in a loop:
For i As Integer = 0 To dtAllFeeds.Rows.Count - 1
    iImported = ImportFeed(dtAllFeeds(i).id)
    totalProductsImported += iImported
    lblStatus.Text += "FeedId: " + dtAllFeeds(i).id.ToString + "Items Imported: " + iImported.ToString
    If iImported = 0 Then
        MailFunctions.NotifyAdmin("feed error: dtAllFeeds(i).id.ToString)
    End If
Next i
lblStatus.Text += "Total imported: " + totalProductsImported.ToString
This works, but as the size or number of feeds increase, so does the time to process them. So I not so elegantly just increased the timeout:
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
    _timeOut = Server.ScriptTimeout
    Server.ScriptTimeout = 36000 '10 hours
End Sub
Now, I want to run these tasks without having to wait for each task to complete before starting the next, so I tried the setup as described here, first with a test function TestMultiThread:
Protected Function TestMultiThread(ByVal Id As Integer, ByVal s As String) As Integer
    LogError("s = " + s)
    For i As Integer = 0 To (Id * 10000)
    Next i
    LogError(Id.ToString + " completed")
    Return Id * 10000
End Function
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim numThreads = 20
Dim toProcess = numThreads
Dim resetEvent = New ManualResetEvent(False)
Dim i As Integer
For i = 1 To numThreads
    ThreadPool.QueueUserWorkItem(New WaitCallback(Sub(state As Object)
                                                      TestMultiThread(i, toProcess.ToString)
                                                      If Interlocked.Decrement(toProcess) = 0 Then
                                                          resetEvent.[Set]()
                                                      End If
                                                  End Sub), Nothing)
Next i
resetEvent.WaitOne()
End Sub
I then get these errors logged:
s = 20
s = 20
s = 20
21 completed
21 completed
21 completed
s = 19
s = 18
s = 17
21 completed
21 completed
s = 16
21 completed
s = 15
21 completed
s = 14
21 completed
s = 13
21 completed
s = 12
21 completed
s = 11
21 completed
s = 10
21 completed
s = 9
21 completed
s = 8
21 completed
s = 7
21 completed
s = 6
21 completed
s = 5
21 completed
s = 4
21 completed
s = 3
21 completed
21 completed
I don't understand this order of logging, howcome I don't see s = <value> for 20 unique values (but s=20 even 3 times in a row in the beginning and missing s=2 and s=1? And why is i always 21 in function TestMultiThread?
 
     
    