157 recommendations for writing high-quality code to improve C # programs--Recommendation 79: Use ThreadPool or BackgroundWorker instead of thread

Source: Internet
Author: User

Recommendation 79: Use ThreadPool or BackgroundWorker instead of thread

The use of threads can greatly improve the user experience, but as a developer it should be noted that the overhead of threads is significant.

The space overhead for threads comes from:

1) Thread kernel objects (thread Kernel object). Each thread creates an object that mainly contains thread context information, which occupies about 700 bytes of memory on a 32-bit system.

2) thread environment block (thread environment block). TEB includes a thread's exception handling chain, which consumes 4KB of memory in 32-bit systems.

3) User mode stack, i.e. line stacks. The thread stack holds the parameters, local variables, and return values of the method. Each thread stack consumes 1024KB of memory. To run out of memory is simple, write a recursive method that does not end, so that the method parameters and return values are constantly consuming memory, OutOfMemoryException will soon occur.

4) kernel-mode stack (Kernel mode stack). When invoking the operating system's kernel-mode functions, the system copies the function parameters from the user-mode stack to the kernel-mode stack. In a 32-bit system, the kernel-mode stack consumes 12KB of memory.

The time overhead for a thread comes from:

1) When threads are created, the system initializes these memory spaces in succession.

2) The CLR then invokes all the DllMain methods that load the DLL and passes the connection flags (when the thread terminates, the DLL's DllMain method is called, and the detach flag is passed).

3) thread context switch. Many processes are loaded in one system, and one process contains several threads. But a CPU can only have one thread executing at any time. In order for each thread to appear to be running, the system will constantly switch "thread context": Each thread will get a dozens of millisecond execution time slice and then switch to the next thread. This process is probably divided into the following 5 steps:

Step 1 enters kernel mode.

Step 2 Saves the context information (primarily some CPU register information) to the executing thread kernel object.

Step 3 The system gets a Spinlock, determines the next thread to execute, and then releases Spinlock. If the next thread is not in the same process, a virtual address exchange is required.

Step 4 uploads The thread kernel object that will be executed into the context information.

Step 5 leave kernel mode.

Because so much work is needed, creating and destroying a thread means that the cost is "expensive". To avoid programmers using threads sparingly, Microsoft developed a "thread pool" technology. Simply put, the thread pool is a developer who manages worker threads. When a job is finished, the CLR does not destroy the thread, but retains the thread for a period of time to see if any other work is needed for the thread. As for when to destroy or new threads, the CLR makes this decision based on its own algorithm. So, if we want to encode multiple threads, we should not expect:

New Thread (() =    {          // Work code       });  


You should first think of relying on the thread pool:

ThreadPool.QueueUserWorkItem ((objstate) ={      // Work code   NULL 


Thread pooling technology allows us to focus on the implementation of the business rather than on the performance testing of the thread.

This recommendation also mentions a type of BackgroundWorker. BackgroundWorker is a technology that uses the thread pool internally, and in WinForm or WPF encoding, it gives the worker and UI threads the ability to interact. If we take a little note, we will find that both thread and threadpool do not provide this interaction capability by default, while BackgroundWorker provides this capability through events. This capability includes reporting progress, supporting completion callbacks, canceling tasks, pausing tasks, and more. A simple example of using BackgroundWorker is as follows:

PrivateBackgroundWorker worker; Private voidStartasyncbutton_click (System.Object sender, System.EventArgs e) {worker. DoWork+=NewDoworkeventhandler (worker_dowork); Worker. ProgressChanged+=NewProgresschangedeventhandler (worker_progresschanged); Worker.  RunWorkerAsync (); }   Private voidWorker_dowork (Objectsender, DoWorkEventArgs e) {BackgroundWorker worker= Sender asBackgroundWorker;  for(inti =0; I <Ten; i++) {worker.          ReportProgress (i); Thread.Sleep ( -); }  }   Private voidWorker_progresschanged (Objectsender, ProgressChangedEventArgs e) {       This. Label1. Text =e.progresspercentage.tostring (); } 


The example is a WinForm form program that is engaged in WinForm or WPF development, and may consider using BackgroundWorker.

Turn from: 157 recommendations for writing high-quality code to improve C # programs Minjia

157 recommendations for writing high-quality code to improve C # programs--Recommendation 79: Use ThreadPool or BackgroundWorker instead of thread

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.