We help IT Professionals succeed at work.

Vb.NET Threading Question

GJDuquette
GJDuquette asked
on
Experts,

I have a project to convert 1000's of tif images to pdf. In order speed up the process i'm trying to use a thread pool.

The code below loops through all the directories/files but only converts a few hundred files (no errors).

I think the issue is how I have implement the threading. Can you enlighten me on the correct threading method?

Imports System.IO
Imports System.Threading
Imports GdPicture14

Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        ' Get recursive List of all files starting in this directory.
        Dim tifFiles As New List(Of String)
        Dim folderStack As New Stack(Of String)
        Dim fileStack As New Stack(Of String)
        Dim currFile As String = ""
        Dim Count = 0
        Dim w As WaitCallback = New WaitCallback(AddressOf cvt1)
        folderStack.Push("C:\testfolder")
        Do While (folderStack.Count > 0)
            ' Get top directory string
            Dim dir As String = folderStack.Pop
            Try
                ' Add all immediate file paths
                If Not Directory.Exists(dir.Replace("C:\", "D:\")) Then
                    Directory.CreateDirectory(dir.Replace("C:\", "D:\"))
                End If
                For Each file In Directory.GetFiles(dir, "*.tif")
                    fileStack.Push(file)
                Next
                Do While (fileStack.Count > 0)
                    currFile = fileStack.Pop
                    ThreadPool.QueueUserWorkItem(w, currFile)
                    ConversionCount.Text += 1
                    ConversionCount.Refresh()
                    currFile = ""
                Loop
                ' Loop through all subdirectories and add them to the stack.
                Dim directoryName As String = ""
                For Each directoryName In Directory.GetDirectories(dir)
                    folderStack.Push(directoryName)
                Next
            Catch ex As Exception
                MsgBox("Error: " & vbCrLf & ex.ToString, MsgBoxStyle.Information, "Error!")
            End Try
        Loop
    End Sub

    Public Function cvt1(ByVal f As String) As String
        Dim oConverter As GdPictureDocumentConverter = New GdPictureDocumentConverter()
        Dim status As GdPictureStatus = oConverter.LoadFromFile(f, GdPicture14.DocumentFormat.DocumentFormatIFF)
        If status = GdPictureStatus.OK Then
            f = f.Replace("C:\", "D:\")
            f = f.Replace(".tif", ".pdf")
            status = oConverter.SaveAsPDF(f, PdfConformance.PDF1_7)
            If status <> GdPictureStatus.OK Then
                MessageBox.Show("The file has failed to save. Status: " + status.ToString(), "TIFF to PDF", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End If
            Return True
        Else
            Return False
            MessageBox.Show("The file has failed to load. Status: " + status.ToString(), "TIFF to PDF Example", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End If
    End Function

End Class
Comment
Watch Question

Developer
CERTIFIED EXPERT
Distinguished Expert 2019
Commented:
Untested but you could do something like this:
Imports System.IO

Public Class Form1
    Private tasks As New List(Of Task)
    Private Sub OnClick(sender As Object, e As EventArgs) Handles Button1.Click
        For Each file In New DirectoryInfo("C:\testfolder").EnumerateFiles("*.*", SearchOption.AllDirectories)
            Dim task = New Task(Of String)(Function()
                                               Dim result = String.Empty
                                               Try
                                                   Dim converter = New GdPictureDocumentConverter()
                                                   Dim status = converter.LoadFromFile(file.FullName, GdPicture14.DocumentFormat.DocumentFormatFF)
                                                   If status = GdPictureStatus.OK Then
                                                       If Not Directory.Exists(file.Directory.FullName.Replace("C:\", "D:\")) Then
                                                           Directory.CreateDirectory(file.Directory.FullName.Replace("C:\", "D:\"))
                                                       End If
                                                       status = converter.SaveAsPDF(file.FullName.Replace("C:\", "D:\").Replace(".tif", ".pdf"), PdfConformance.PDF1_7)
                                                       If status <> GdPictureStatus.OK Then
                                                           result = $"The file has failed to save. Status {status}"
                                                       Else
                                                           result = $"Successfully saved file - {file} to {file.FullName.Replace("C:\", "D:\").Replace(".tif", ".pdf")}"
                                                       End If
                                                   End If
                                               Catch ex As Exception
                                                   result = $"The file has failed to save. Execption caugth - {ex.Message}"
                                               End Try
                                               Return result
                                           End Function)
            task.Start()
            tasks.Add(task)
        Next
        Task.WhenAll(tasks.ToArray()).ContinueWith(Sub() MessageBox.Show("Finished converting files", "TIFF to PDF", MessageBoxButtons.OK))
    End Sub
End Class

Open in new window

-saige-

Author

Commented:
Thanks Saige! Works perfectly!