使用参数化函数(x,y,z)的 for 循环中的多个线程

Multiple threads in a for-loop using a parameterized function(x, y, z)

我有一个包含文件夹 ID 和文件夹路径的列表。我想将其中一些文件夹传递给一个压缩它们的函数。我想要的是并行三个线程 运行 并一次压缩三个不同的路径。现在发生的是每个线程等待直到下一个线程完成才能处理下一个。有什么想法吗?

Dim SelectedRange = From folders In listFolders Where folders.FolderID >= 150101

For Each item In SelectedRange
    Dim t As New Thread(
        Sub()
            Me.BeginInvoke(DirectCast(Sub() ZipFolder(sInclearDestination, item.FolderID.ToString, item.FolderPath), MethodInvoker))
        End Sub)
    t.Start()
    t.Join()
Next

Public Function ZipFolder(ByVal sFolderPathDestination As String, ByVal folderID As String, ByVal folderPath As String) As Boolean
    Try
        Using zip = New Ionic.Zip.ZipFile()
            'If the zip file does not exist then get the folder and zip it to the destination
            If Not File.Exists(Path.Combine(sFolderPathDestination, folderID & ".zip")) Then
                zip.AddDirectory(folderPath)
                zip.Save(Path.Combine(sFolderPathDestination, CType(folderID, String) & ".zip"))
                Return True
            Else
                Logging.Log("Aborting zipping: " & Path.Combine(sFolderPathDestination, folderID & ".zip") & ". The zip file already exists!")
                Return False
            End If
        End Using
    Catch ex As Exception
        Logging.Log("Error in zipping: " & Path.Combine(sFolderPathDestination, folderID & ".zip") & " Error: " & ex.Message)
        Return False
    End Try
End Function

您的代码有两个问题。

第一个问题是对Me.BeginInvoke的调用。假设您正在创建一个 WinForm 应用程序并且 Me 是对当前 Form 的引用。 Form.BeginInvoke(继承自基础 Control class)导致给定的委托在 UI 线程上执行。因此,您所做的就是创建三个独立的线程,它们都立即调用回 UI 线程来完成它们的所有工作。您显然不能那样做,并且仍然希望并行处理这些任务。您需要删除对 BeginInvoke 的调用。如果您需要调用 BeginInvoke 以更新表单上某些数据的显示,您需要尽可能晚地执行此操作,并在 UI 调用的代码中做尽可能少的工作这样大部分工作仍在工作线程中完成。

第二个问题是对Thread.Join的调用。您在启动线程后立即在 For 循环中调用 Join 。这意味着它将坐在那里等待,在调用 Join 时,直到工作线程完成。因此,您的循环在开始下一个线程之前等待每个线程完成,本质上,使其成为单线程。您应该只删除对 Join 的调用。如果您需要调用方法等待所有线程完成,只需等待在线程上调用 Join 直到 all 它们已经启动(即在 For循环)。