Thread pooling is a form of multithreading where tasks are added to a queue and automatically started as threads are created. With thread pooling, you call the Threadpool.QueueUserWorkItem method with a delegate for the procedure you want to run, and Visual Basic .NET creates the thread and runs your procedure. The following example shows how you could use thread pooling to start several tasks.
Sub DoWork() Dim TPool As System.Threading.ThreadPool ' Queue a task TPool.QueueUserWorkItem(New System.Threading.WaitCallback _ (AddressOf SomeLongTask)) ' Queue another task TPool.QueueUserWorkItem(New System.Threading.WaitCallback _ (AddressOf AnotherLongTask)) End Sub
Thread pooling is useful when you want to start many separate tasks without individually setting the properties of each thread. Each thread starts with a default stack size and priority. By default, up to 25 thread pool threads can run per system processor. Additional threads in excess of the limit can be queued, but they do not start until other threads finish.
One advantage of thread pooling is that you can pass arguments in a state object to the task procedure. If the procedure you are calling requires more than one argument, you can cast a structure or an instance of a class into an Object data type.
Thread Pool Parameters and Return Values
Returning values from a thread pool thread is not straightforward. The standard way of returning values from a function call is not allowed because Sub procedures are the only type of procedure that can be queued to a thread pool. One way you can provide parameters and return values is by wrapping the parameters, return values, and methods in a wrapper class as described in Parameters and Return Values for Multithreaded Procedures. An easer way to provide parameters and return values is by using the optional ByVal state object variable of the QueueUserWorkItem method. If you use this variable to pass a reference to an instance of a class, the members of the instance can be modified by the thread pool thread and used as return values. At first it may not be obvious that you can modify an object referred to by a variable that is passed by value. This is possible because only the object reference is passed by value. When you make changes to members of the object referred to by the object reference, the changes apply to the actual class instance.
Structures cannot be used to return values inside state objects. Because structures are value types, changes that the asynchronous process makes do not change the members of the original structure. Use structures to provide parameters when return values are not needed.
Multithreaded Applications | ThreadPool.QueueUserWorkItem Method | Thread Timers | Thread Synchronization | Parameters and Return Values for Multithreaded Procedures | Multithreading with Forms and Controls | System.Threading Namespace | SyncLock Statement