我有一个包含文件夹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
答案 0 :(得分:3)
您的代码存在两个问题。
第一个问题是对Me.BeginInvoke
的调用。大概你正在创建一个WinForm应用程序,而Me
是对当前Form
的引用。 Form.BeginInvoke
(继承自基类Control
类)导致给定的委托在UI线程上执行。所以,你所做的只是创建三个独立的线程,它们都会立即调用回UI线程来完成所有工作。你显然不能这样做,仍然期望并行处理任务。您需要移除对BeginInvoke
的通话。如果您需要按顺序调用BeginInvoke
来更新表单上某些数据的显示,您需要尽可能晚地执行此操作,并在该UI调用的代码中尽可能少地工作,以便大多数工作仍然在工作线程中完成。
第二个问题是对Thread.Join
的调用。您在启动线程后立即在Join
循环内调用For
。这意味着它将坐在那里并等待Join
的调用,直到工作线程完成。因此,你的循环在开始下一个线程之前等待每个线程完成,实质上是使它成为单线程。您应该删除对Join
的调用。如果您需要调用方法来等待所有线程完成,只需等待线程上的Join
,直到所有已经启动(即For
之后循环)。