Wednesday, 11 September 2013

VB.NET, best practice for sorting concurrent results of threadpooling?

VB.NET, best practice for sorting concurrent results of threadpooling?

In short, I'm trying to "sort" incoming results of using threadpooling as
they finish. I have a functional solution, but there's no way in the world
it's the best way to do it (it's prone to huge pauses). So here I am! I'll
try to hit the bullet points of what's going on/what needs to happen and
then post my current solution.
The intent of the code is to get information about files in a directory,
and then write that to a text file.
I have a list (Counter.ListOfFiles.First) that is a list of the file paths
sorted in a particular way. This is the guide that dictates the order I
need to write to the text file.
I'm using a threadpool to collect the information about each file, create
a stringbuilder with all of the text ready to write to the text file. I
then call a procedure(SyncUpdate, inlcluded below), send the
stringbuilder(strBld) from that thread along with the name of the path of
the file that particular thread just wrote to the stringbuilder
about(Xref).
The procedure includes a synclock to hold all the other threads until it
finds a thread passing the correct information. That "correct" information
being when the xref passed by the thread matches the first item in my list
(FirstListItem). When that happens, I write to the text file, delete the
first item in the list and do it again with the next thread.
The way I'm using the monitor is probably not great, in fact I have little
doubt I'm using it in an offensively wanton manner. Basically while the
xref (from the thread) <> the first item in my list, I'm doing a pulseall
for the monitor. I originally was using monitor.wait, but it would
eventually just give up trying to sort through the list, even when using a
pulse elsewhere. I may have just been coding something awkwardly. Either
way, I don't think it's going to change anything.
Basically the problem comes down to the fact that the monitor will pulse
through all of the items it has in the queue, when there's a good chance
the item I am looking for probably got passed to it somewhere earlier in
the queue or whatever and it's now going to sort through all of the items
again before looping back around to find a criteria that matches. The
result of this is that my code will hit one of these and take a huge
amount of time to complete.
I'm open to believing I'm just using the wrong tool for the job, or just
not using tool I have correctly. I would strongly prefer some sort of
threaded solution (unsurprisingly, it's much faster!). I've been messing
around a bit with the Parallel Task functionality today, and a lot of the
stuff looks promising, but I have even less experience with that vs.
threadpool, and you can see how I'm abusing that! Maybe something with
queue? You get the idea. I am directionless. Anything someone could
suggest would be much appreciated. Thanks! Let me know if you need any
additional information.
Private Sub SyncUpdateResource(strBld As Object, Xref As String)
SyncLock (CType(strBld, StringBuilder))
Dim FirstListitem As String = CountsALot.ListOfFiles.First
Do While Xref <> FirstListitem
FirstListitem = Counter.ListOfFiles.First
'This makes the code much faster for reasons I can only guess at.
Thread.Sleep(5)
Monitor.PulseAll(CType(strBld, StringBuilder))
Loop
Dim strVol As String = Form1.Volname
Dim strLFPPath As String = Form1.txtPathDir
My.Computer.FileSystem.WriteAllText(strLFPPath & "\" & strVol &
".txt", strBld.ToString, True)
CountsALot.ListOfFiles.Remove(Xref)
End SyncLock
End Sub

No comments:

Post a Comment