我有一个阻塞集合,其中填充了数据库中的记录列表。
Public Shared BatchRecords As IThreadPool(Of BatchRecord) = New IThreadPool(Of BatchRecord)(Function() Return New BatchRecord End Function, 20)
Public Shared Function GetOne(ThreadName As String) As BatchRecord
Dim record As BatchRecord = BatchRecords.GetRecord()
log.WriteLog("Thread:" & ThreadName & " Pool: " & Pool.ToString)
Return record
End Function
Public Shared Sub AddOne(record As BatchRecord)
BatchRecords.PutRecord(record)
End Sub
Task.Factory.StartNew(Sub()
PoolForBatchRecords()
End Sub)
For i As Integer = 0 To 20
Task.Factory.StartNew(Sub()
Dim BatchGenerator As New GeneratorThread
Thread.CurrentThread.Name = (i + 1).ToString
BatchGenerator.Run()
End Sub)
Next
Inside GeneratorThread
Public Function Run()
while true
Dim record as MyRecord = MyCollection.Take()
'Do Work
End While
End Function
我的20个任务正在查询BlockingCollection中的项目。但线程不断获得相同的项目。集合中没有重复项。事实上,当它开始66879524时,集合中只有一个项目。
Adding BatchId: 66879524 2018/05/29 14:20:01
Thread:1 picking up Batch ID:66879524 2018/05/29 14:20:02
Thread:2 picking up Batch ID:66879524 2018/05/29 14:20:02
Adding BatchId: 66879531 2018/05/29 14:20:02
答案 0 :(得分:0)
最终在将项目添加到列表中时出现
20使所有线程都从数据库中检查项目进行处理。检查是在while循环中
Dim record As BatchRecord = Nothing
Dim keepChecking As Boolean = true
while keepChecking
'Stop when we find a record
keepChecking = CheckforWork(byRef record)
End While
BatchRecords.AddOne(record)
while循环应该在返回错误的keepChecking时立即停止,但是实际上设置了keepChecking时,while循环继续循环了2-3次。
我通过传入keepChecking byRef进行了修复,它将立即将变量设置为false,然后返回我发现的记录:
Dim record As BatchRecord = Nothing
Dim keepChecking As Boolean = true
while keepChecking
'Stop when we find a record
record = CheckforWork(byRef keepChecking)
End While
这不是确切的代码,当然还有一些其他检查,并且在检查之间会有一个暂停,以免影响数据库,尤其是当找到0条记录时。