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

在vb.net中,每次将对象传入循环中的线程,.net,vb.net,.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 Fo

我不是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不允许我将变量传递给该函数。有没有办法解决这个问题并满足我的要求?非常感谢。

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

并在循环中使用它:

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个线程,这可能不是您想要的。您可能应该研究,这将使用线程池将并发线程限制在更合理的范围内-可能是一个循环。

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

并在循环中使用它:

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个线程,这可能不是您想要的。您可能应该研究,这将使用线程池将并发线程限制在更合理的范围内-可能是一个循环。

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

并在循环中使用它:

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个线程,这可能不是您想要的。您可能应该研究,这将使用线程池将并发线程限制在更合理的范围内-可能是一个循环。

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

并在循环中使用它:

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个线程,这可能不是您想要的。您可能应该研究,这将使用线程池将并发线程限制在更合理的范围内—可能是一个循环。

您通常可以这样做:

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

这不会创建太多线程,应该可以最大限度地提高性能。

通常可以这样做:

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

这不会创建太多线程,应该可以最大限度地提高性能。

通常可以这样做:

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

这不会创建太多线程,应该可以最大限度地提高性能。

通常可以这样做:

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))
这不会创建太多线程,应该可以最大限度地提高性能。

为了使它能够编译(并且假设您的
图像(T1,T2)
甚至是一个真实类型),您只需将
的AddressOf
更改为
Sub()
。然而,这整件事需要重新思考:在循环中启动并忘记线程?听起来是个坏主意。为了使它能够编译(并且假设你的
图像(T1,T2)
甚至是一个真正的类型),你只需要将
AddressOf
更改为
Sub()
。然而,这整件事需要重新思考:在循环中启动并忘记线程?听起来是个坏主意。为了使它能够编译(并且假设你的
图像(T1,T2)
甚至是一个真正的类型),你只需要将
AddressOf
更改为
Sub()
。然而,这整件事需要重新思考:在循环中启动并忘记线程?听起来是个坏主意。为了使它能够编译(并且假设你的
图像(T1,T2)
甚至是一个真正的类型),你只需要将
AddressOf
更改为
Sub()
。然而,这整件事需要重新思考:在循环中启动并忘记线程?听起来是个坏主意。