rerat rerat - 24 days ago 11
Vb.net Question

Need help dynamically creating threads in VB.Net

I am using VB.Net 2010. I have a function that checks a database for requests and some of the requests can take several minutes to complete. I don't want it to queue up while requests are being processed, so I want to dynamically create new threads to run each new request so that they can be ran simultaneously. I was not sure if I should use threads, threadpools, background workers or something else. Any suggestions and sample code would be great. I can work with a simple example. This is all I have so far.

Thank You.

Imports System.Threading
Module Module1
Private trd As Thread
Sub Main()
'START THREAD
trd = New Thread(AddressOf command_loop)
trd.IsBackground = True
trd.Start()

Console.ReadLine()
End Sub
Function command_loop()
'CREATE EXPORT FILE
Try
Dim f As FileInfo
Dim export As System.IO.StreamWriter
Dim arr_comment

'DELETE OLD EXPORT FILE
If File.Exists(export_path) Then
File.Delete(export_path)
End If

'VERIFY OLD EXPORT FILE WAS DELETED
If File.Exists(export_path) Then
writeToLog("ERROR: Old export file for " & username & " was not able to be deleted")
End If

'GET USER FOLDER CRC
Dim di As New DirectoryInfo(user_folder)
Dim fiArr As FileInfo() = di.GetFiles()
export = My.Computer.FileSystem.OpenTextFileWriter(export_path, True)
export.WriteLine("filepath, size, esize, date_mod_timestamp, timestamp, remote_filename, filestatus")

For Each f In fiArr
Try
Using zip As ZipFile = ZipFile.Read(user_folder & "\" & f.Name)
For Each e As ZipEntry In zip
If (zip.Comment IsNot Nothing) AndAlso (zip.Comment <> "") Then
arr_comment = Split(zip.Comment, ":")
End If

If arr_comment.length <> 3 Then
'FILE HAS AN INVALID COMMENT, SO DELETE IT.
zip.Dispose()

Try
writeToLog("Invalid zip file comment, deleting file " & user_folder & "\" & f.Name)
File.Delete(user_folder & "\" & f.Name)
writeToLog("Zip file successfully deleted")
Catch exx As Exception
writeToLog("Unable to delete invalid zip file")
writeToLog(exx.Message)
End Try
Continue For
End If

'CORRECT FILE PATH
Dim filepath = Replace(e.FileName, "/", "\\")

export.WriteLine(Chr(34) & filepath & Chr(34) & "," & e.UncompressedSize & "," & e.CompressedSize & "," & arr_comment(1) & "," & arr_comment(2) & "," & f.Name & "," & arr_comment(0))
Exit For
Next
End Using
Catch ex As IOException
Console.WriteLine(ex.Message)
Catch ex As ZipException
Console.WriteLine(ex.Message)
Try
writeToLog("Invalid zip file, deleting file " & user_folder & "\" & f.Name)
File.Delete(user_folder & "\" & f.Name)
writeToLog("Zip file successfully delete")
Catch e As Exception
writeToLog("Unable to delete invalid zip file")
writeToLog(e.Message)
End Try
End Try
Next f
export.Close()
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try

End Function
End Module

Answer

I use the thread pool for this type of a task. It's much lighter weight than spawning new threads and the background worker only supports one thread per worker.

Private Class MyArgs
    'add things for cancellation / storing results in here
End Class

Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    Dim args As New MyArgs()
    Threading.ThreadPool.QueueUserWorkItem(AddressOf DoThisSingleThing, New MyArgs)
End Sub

Private Sub DoThisSingleThing(state As Object)
    Dim args = CType(state, MyArgs)

    While Not args.Cancel

    End While

    args.Result = ...

    'If you need to update the UI afterward then invoke onto its thread.
    Me.BeginInvoke(Sub() OnComplete(args))
End Sub


Private Sub OnComplete(args As MyArgs)

End Sub