Pass an object in to a thread in a loop each time in

I'm not an expert in so this is kind of a frustrating problem for me. I need read images from a directory and process them parallely. SO ideally what my code should do is,

Dim Directory As New IO.DirectoryInfo("New Folder\\")
   Dim allFiles As IO.FileInfo() = Directory.GetFiles("*.bmp")
    Dim singleFile As IO.FileInfo
    Dim i As Integer = 0
    For Each singleFile In allFiles

        If File.Exists(singleFile.FullName) Then
            Dim badge As Image(Of Bgr, Byte) = New Image(Of Bgr, Byte)        (singleFile.FullName)
            i = i + 1
            Dim checkLabelThread As Thread = New Thread(AddressOf processBadge(badge, i))
        End If

Here, processBadge is the function that should process the badge. But does not allow me to pass variables in to that function. Is there a work around to fix this and fulfill my requirement? Thanks a lot.


You can generally do this:

Dim checkLabelThread As Thread = New Thread(Sub() processBadge(badge, i))

Note the replacement of AddressOf with Sub().

However, because you are threading the value of i will update before the thread executes so you'll never get the actual value of i - the loop will have finished so the value will be count of the items in the allFiles array.

So here's what I'd do.

First I'd create an overload of processBadge to make the calling code cleaner. Like this:

Private Sub processBadge(fileInfo As FileInfo, index As Integer)
    If File.Exists(fileInfo.FullName) Then
        Dim badge As Image(Of Bgr, Byte) = _
            New Image(Of Bgr, Byte)(singleFile.FullName)
        processBadge(badge, index)
    End If
End Sub

Then I'd call it using Parallel.ForEach like this:

Dim source = new System.IO.DirectoryInfo("New Folder\\") _
    .GetFiles("*.bmp") _
    .Select(Function(f, i) New With { .FileInfo = f, .Index = i })
Parallel.ForEach(source, Sub(x) processBadge(x.FileInfo, x.Index))

That won't create too many threads and should maximize the performance.

You could create a class to hold your thread context information (untested code follows):

Public Class BadgeProcessor
    Private ReadOnly _badge As Image
    Private ReadOnly _index As Integer
    Public Sub New(badge As Image, index As Integer)
        _badge = badge
        _index = index
    End Sub
    Public Sub ProcessBadge()
        ' do what your processBadge method does here
    End Sub
End Class

And use that in your loop:

If File.Exists(singleFile.FullName) Then
    Dim badge As Image(Of Bgr, Byte) = New Image(Of Bgr, Byte)(singleFile.FullName)
    i = i + 1
    Dim bp As BadgeProcessor = New BadgeProcessor(badge, i)
    Dim checkLabelThread As Thread = New Thread(AddressOf bp.ProcessBadge)
    'checkLabelThread.Start() ?
End If

However, if you have 1000 images in the directory, you are going to start 1000 threads, which is probably not going to be what you want. You should probably investigate the Task Parallel Library, which would use a thread pool to limit the concurrent threads to something more reasonable - perhaps a Parallel.ForEach loop.

Need Your Help

Detail view on Map in Iphone SDK

iphone ios objective-c xcode mkmapview

In my app,I implemented a map View & added the annotations.

Hide file extension

javascript html asp-classic web-config

I want to remove the file-extension (like .html) for users of IE, FF and google Chrome.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.