线程池

更新: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 状态对象变量。如果使用此变量来传递对类实例的引用,则该实例的成员可以由线程池线程进行修改,并用作返回值。

最初,可以修改由按值传递的变量所引用的对象可能并不明显。由于只有对象引用按值传递,因此您可以这样做。当您对由对象引用所引用的对象的成员进行更改时,这些更改将应用于实际的类实例。

不能使用结构在状态对象内部返回值。由于结构属于值类型,异步进程所做的更改不会更改原结构的成员。如果不需要返回值,可以使用结构来提供参数。

请参见

概念

高级多线程处理 (Visual Basic)

多线程应用程序

线程同步

多线程处理窗体和控件

参考

QueueUserWorkItem

System.Threading

SyncLock 语句