每次在vb.net中将对象传递给循环中的线程

时间:2014-06-29 02:26:30

标签: .net vb.net

我不是vb.net的专家,所以这对我来说是一个令人沮丧的问题。我需要从目录中读取图像并并行处理它们。理想情况下,我的代码应该做的是,

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
        Console.WriteLine(singleFile.FullName)

        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
    Next`

这里,processBadge是应该处理徽章的功能。但是Vb.net不允许我将变量传递给该函数。有没有解决这个问题并满足我的要求的工作?非常感谢。

2 个答案:

答案 0 :(得分:2)

您通常可以这样做:

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

请注意将AddressOf替换为Sub()

但是,因为你是线程,i的值会在线程执行之前更新,所以你永远不会得到i的实际值 - 循环将完成所以值将会计算allFiles数组中的项目。

所以,这就是我要做的事情。

首先,我创建了processBadge的重载,以使调用代码更清晰。像这样:

Private Sub processBadge(fileInfo As FileInfo, index As Integer)
    Console.WriteLine(fileInfo.FullName)
    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

然后我会使用Parallel.ForEach这样称呼它:

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))

这不会创建太多线程并且应该最大化性能。

答案 1 :(得分:1)

您可以创建一个类来保存您的线程上下文信息(未经测试的代码如下):

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

在你的循环中使用它:

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

但是,如果目录中有1000个图像,则将启动1000个线程,这可能不是您想要的。您应该调查Task Parallel Library,它将使用线程池将并发线程限制为更合理的 - 可能是Parallel.ForEach循环。