I don't think the sorting makes any sense. If you're processing the list in parallel, the items can be processed in any order.
The
List(Of T)
class is not a good choice. It's not thread-safe, and removing items from the start of the list is an expensive operation. I'd suggest using the
ConcurrentQueue(Of T)[
^] class instead.
You'll need an extension method to get a "consuming" enumerator, that removes items from the queue as they're processed:
Module CollectionExtensions
<Extension()>
Public Iterator Function GetConsumingEnumerator(Of T)(ByVal source As IProducerConsumerCollection(Of T)) As IEnumerable(Of T)
Dim item As T
While source.TryTake(item)
Yield item
End While
End Function
End Module
You can then use the
AsParallel[
^] extension method to consume the list in parallel:
Dim best As B = Nothing
Dim initialList As New List(Of B)
Populate(initialList)
Dim mainList As New ConcurrentQueue(Of B)(initialList)
While Not mainList.IsEmpty
Dim newItems As IEnumerable(Of List(Of B)) = mainList _
.GetConsumingEnumerator() _
.AsParallel() _
.Where(Function (current) best Is Nothing OrElse current.Result <= best.Result) _
.Select(Function (current) PerformWork(current)) _
.Where(Function (newList) newList.Count > 0)
For Each newList As List(Of B) In newItems
If newList(0).IsFinal Then
If best Is Nothing OrElse best.Result > newList(0).Result Then
best = newList(0)
End If
Else
For Each item As B In newList
mainList.Enqueue(item)
Next
End If
Next
End While
NB: You have a mistake in your current code:
If Best IsNot Nothing OrElse Best.Result > SubList(0).Result then
If
Best
is
Nothing
, you'll get a
NullReferenceException
on that line.