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

时间:2015-01-28 18:26:00

标签: vb.net multithreading

我有一个包含文件夹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

1 个答案:

答案 0 :(得分:3)

您的代码存在两个问题。

第一个问题是对Me.BeginInvoke的调用。大概你正在创建一个WinForm应用程序,而Me是对当前Form的引用。 Form.BeginInvoke(继承自基类Control类)导致给定的委托在UI线程上执行。所以,你所做的只是创建三个独立的线程,它们都会立即调用回UI线程来完成所有工作。你显然不能这样做,仍然期望并行处理任务。您需要移除对BeginInvoke的通话。如果您需要按顺序调用BeginInvoke来更新表单上某些数据的显示,您需要尽可能晚地执行此操作,并在该UI调用的代码中尽可能少地工作,以便大多数工作仍然在工作线程中完成。

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