好的,这是我的代码:
For i = 0 To 10
Dim tTemp As Threading.Thread = New Threading.Thread(AddressOf dwnld)
tTemp.IsBackground = True
'tTemp.Start(geturl)
lThreads.Add(tTemp)
'MsgBox(lThreads.Item(i).ThreadState)
Next
我创建了一个包含10个线程的线程列表,为它们分配了一个函数,属性并将它们添加到列表中。
'While ListBox2.Items.Count > 0
For i = 0 To lThreads.Count - 1
If (lThreads.Item(i).ThreadState = 12) Then
If (ListBox2.Items.Count > 0) Then
lThreads.Item(i).Start(geturl)
If (i = lThreads.Count - 1) Then
i = 0
End If
Else
Exit For
End If
'MsgBox(lThreads.Item(i).ThreadState)
ElseIf (lThreads.Item(i).ThreadState = 16) Then
lThreads.RemoveAt(i)
Dim tTemp As Threading.Thread = New Threading.Thread(AddressOf dwnld)
tTemp.IsBackground = True
lThreads.Add(tTemp)
If (i = lThreads.Count - 1) Then
i = 0
End If
End If
Next
发生的事情是,我看到线程在dwnld函数完成后停止。所以我首先检查状态(12表示背景和未启动)。在案例12中启动线程,在案例16(停止)中删除该特定线程并添加一个不同的线程,如我在上面添加10个。
当i计数器到达最后一个数字时,还会检查,通过指定i = 0重新启动整个循环。
程序下载一些网页,网址从listbox2传递。 geturl将传递url并将其从列表中删除。因此,当列表框为空时,退出for循环。
但是上面的代码只运行了11次而且没有重启。我尝试使用标签和goto,但它很简单。
谁能告诉我该怎么做?
我想要的是保持10个线程以继续下载网页,当列表为空时,退出该功能。
答案 0 :(得分:2)
尝试手动管理自己的自定义线程池可能是错误的方法。使用ThreadPool.QueueUserWorkItem
或者最好使用新的Task
课程。为您管理线程池,这极大地简化了代码。完全废弃此代码并重新使用我刚才提到的技术之一。如果您在实施这些技术中遇到问题,请发布更具体的问题。
答案 1 :(得分:1)
线程的微观管理是一个非常糟糕的主意。当我看到有人试图维护一系列不断创建,终止和销毁的线程时,我才知道它们注定要失败。我见过有经验的专业人士试图这样做 - 看起来很有趣,等待几个月试图修复无法修复后不可避免的壮观失败。
线程池通常不是那种类型。它们通常是一个任务池 - 生产者 - 消费者队列上的任务类实例 - 当它们可以自由地工作时,几个线程会反馈它们。工作线程通过在完成旧任务时自行获取新任务来自动管理自己 - 无需任何更高级别的微观管理。
听@Brian - 忘记管理线程列表,检查他们的状态和所有gunge。这只会让你生病。使用ThreadPool.QUWI或任务。