2014-06-29 50 views
0

我不是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不允許我將變量傳遞給該函數。有沒有解決這個問題並滿足我的要求的工作?非常感謝。

+0

爲了讓它編譯(並且假設你的'Image(Of T1,T2)'甚至是一個真正的類型),你只需要改變'AddressOf'到'Sub()'。然而,這整個事情需要重新思考:循環內部的遺忘線程?聽起來不是一個好主意。 –

回答

2

通常你可以做到這一點。

但是,因爲你穿的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)) 

這不會創造太多的線程,應該最大限度地提高性能。

+0

這一個工程。非常感謝 – SameeraR

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循環。與Sub()

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

注意更換AddressOf

相關問題