我正在运行一个从各种商店导入产品信息的网站。这些提要可能非常大,有些高达 1GB。目前我通过在循环中调用导入函数来导入这些:
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
这可行,但随着提要的大小或数量增加,处理它们的时间也会增加。所以我不那么优雅地增加了超时时间:
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
现在,我想运行这些任务,而不必在开始下一个任务之前等待每个任务完成,所以我尝试了这里描述的设置,首先使用测试功能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
然后我记录了这些错误:
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
我不明白这种记录顺序,为什么我没有看到s = <value>
20 个唯一值(但s=20
在开始时甚至连续 3 次并且丢失了s=2
?s=1
为什么i
总是 21 在函数中TestMultiThread
?