线程池
更新:2007 年 11 月
线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。对于线程池,可使用要运行的过程的委托调用 ThreadPool.QueueUserWorkItem 方法,而 Visual Basic 将创建线程并运行您的过程。
线程池示例
下面的示例说明如何使用线程池来启动几个任务。
Sub DoWork()
' Queue a task
System.Threading.ThreadPool.QueueUserWorkItem( _
New System.Threading.WaitCallback(AddressOf SomeLongTask))
' Queue another task
System.Threading.ThreadPool.QueueUserWorkItem( _
New System.Threading.WaitCallback(AddressOf AnotherLongTask))
End Sub
Sub SomeLongTask(ByVal state As Object)
' Insert code to perform a long task.
End Sub
Sub AnotherLongTask(ByVal state As Object)
' Insert code to perform another long task.
End Sub
如果需要启动多个不同的任务,而不想分别设置每个线程的属性,则可以使用线程池。每个线程启动时具有默认堆栈大小和优先级。默认情况下,每个系统处理器最多可以运行 25 个线程池线程。超过此限制的其他线程可以排队,但它们要等到其他线程完成后才启动。
线程池的一个优点是可以通过一个状态对象将参数传递到任务过程。如果要调用的过程需要多个参数,可将结构或类的实例强制转换为 Object 数据类型。
线程池参数和返回值
不能直接从线程池线程返回值。不允许使用通过调用函数来返回值的标准方法,因为 Sub 过程是唯一一种可以添加到线程池队列中的过程。一种提供参数和返回值的方法是将参数、返回值和方法包装在一个包装类中,如多线程过程的参数和返回值中所述。
另一种较为简单的提供方法是使用 QueueUserWorkItem 方法的可选 ByVal 状态对象变量。如果使用此变量来传递对类实例的引用,则该实例的成员可以由线程池线程进行修改,并用作返回值。
最初,可以修改由按值传递的变量所引用的对象可能并不明显。由于只有对象引用按值传递,因此您可以这样做。当您对由对象引用所引用的对象的成员进行更改时,这些更改将应用于实际的类实例。
不能使用结构在状态对象内部返回值。由于结构属于值类型,异步进程所做的更改不会更改原结构的成员。如果不需要返回值,可以使用结构来提供参数。