Hi, I’m Hui.

The previous two articles covered the basics of threading and thread synchronization. Let’s learn more about the use of thread pools.

The thread pool

Creating a thread is an expensive operation, so creating a thread for each transient asynchronous operation incurs significant overhead. In general, you use pools, or thread pools, for management.

Thread pools can be successfully adapted to any resource that requires a large number of short-lived and expensive resources. Allocate certain resources in advance and add them to the resource pool. Each time a new resource is needed, it is simply fetched from the pool, no new one is created, and when the resource is no longer in use, it is returned to the pool.

In.net, thread pools can be of type ThreadPool. NET Common Language runtime (CLR) management. Each CLR has a thread pool instance. The ThreadPool type has a QueueUserWorkItem static method. This method receives a delegate representing a user-defined asynchronous operation. When this method is called, the delegate is put into the internal queue, and if there are no threads in the thread pool, a new worker thread is created and the first delegate in the queue is put into that worker thread.

It is important to keep operations in the thread transient. Do not put long-running operations in the thread pool or block worker threads. This causes all worker threads to become too busy to service user operations. This can lead to performance problems and very hard-to-tune errors.

In a thread pool, if you stop placing new operations to it, the thread pool eventually deletes unused threads that expire after a certain amount of time. This frees up all those system resources that are no longer available.

Thread pools are used to perform short-running operations. Using thread pools can reduce parallelism costs and save operating system resources.

The worker threads in the thread pool are background threads. This means that when all foreground threads (including the main thread) have finished, all background threads will stop working.

Use of asynchrony in thread pools

class Program { private delegate string RunOnThreadPool(out int threadId); Private static void Callback(IAsyncResult ar) {console. WriteLine(" trigger Callback "); Console.WriteLine(" AsyncState: "+ ar.AsyncState); Console. WriteLine (" is the Thread pool threads: "+ Thread. The CurrentThread. IsThreadPoolThread); Console. WriteLine (" ThreadId: "+ Thread. CurrentThread. ManagedThreadId); } private static string Test(out int threadId) {Console.WriteLine("Test start "); Console. WriteLine (" is the Thread pool threads: "+ Thread. The CurrentThread. IsThreadPoolThread); Thread.Sleep(TimeSpan.FromSeconds(2)); threadId = Thread.CurrentThread.ManagedThreadId; Return "ThreadId: "+ ThreadId; } static void Main(string[] args) { int threadId=0; RunOnThreadPool poolDelegate=Test; var t=new Thread(()=>Test(out threadId)); t.Start(); t.Join(); Console.WriteLine("Thread ID="+threadId); IAsyncResult ar= pooldelegate. BeginInvoke(out threadId,Callback," test whether to Callback "); ar.AsyncWaitHandle.WaitOne(); string result=poolDelegate.EndInvoke(out threadId,ar); Console. WriteLine (" ID: "+ threadId); Console.WriteLine(" result: "+result); Console.ReadKey(); }}Copy the code

After execution, you can see the actual display results.

Since the thread’s constructor can only accept a method that returns nothing, lambda expressions are used to wrap calls to the Test method.

The above is a very standard example of using delegates in a thread pool, and you can also learn about the use of a specific thread pool. You can see that the first time there is no thread in the pool, it prints out that thread 10 is not in the thread, and the second time it is in the pool, the subsequent asynchronous callback displays the result as thread 11 being called again.

The BeginInvoke method accepts a callback function that will be called after the asynchronous operation completes, and a user-defined state is passed to the callback function. This state is usually used to distinguish asynchronous calls and is a Result object that implements the IAsyncResult interface. BeginInvoke returns the result immediately, and while the worker thread in the thread pool is performing an asynchronous operation, other work is still allowed to continue, and the result can be polled via the IsCompleted property of the Result object. When the operation completes, a result is obtained, and the EndInvoke method can be called through the delegate, passing the IAsyncResult object to the delegate parameter.

If you want to get a result from a thread, you have to use this kind of asynchronous delegate.

It is important to call the EndInvoke method when using a delegate in a thread pool. This method throws any unhandled exceptions back into the calling thread. When using this asynchronous API, be sure to always call the Begin and End methods.

The Begin/End methods used above and. NET IAsyncResult objects and other methods are called asynchronous programming model (APM pattern), such methods are called asynchronous methods.

There is a useful way to thread pool: ThreadPool. RegisterWaitForSingleObject. This method allows us to put the callback function into a queue in the thread pool. This callback function is called when the supplied wait event handler receives a signal or a timeout occurs.

Using the BackgroundWorker component in the thread pool, you can explicitly indicate that the BackgroundWorker thread supports cancellation and notification of action progress. You can use event syntax at this point.

Events represent the source of some notification or a series of subscribers that will respond when the notification arrives.

This is called event-based asynchronous mode (EAP), which starts an asynchronous operation and then subscribes to different events that are fired when the operation is executed.

Small remarks

Life is short, I don’t want to go after what I can’t see, I just want to catch what I can see.

Original is not easy, give a attention.

I am Hui, thank you for reading, if it is helpful to you, please like, forwarding thank you.