SoFunction
Updated on 2025-05-13

How C# multithreaded programming evolves from user thread to thread pool

1. Introduction

In multi-threaded programming, threads are the core of implementing concurrent execution. As a powerful modern programming language, C# provides rich thread management mechanisms to support developers in dealing with various concurrent scenarios. Different thread types have their own emphasis on functions, life cycles and applicable scenarios. Understanding different types of threads and their features is essential to writing efficient, maintainable applications. This article will focus on the five main thread types in C#:

  • User Threads

  • Daemon Threads

  • Main Thread

  • Worker Threads

  • Thread Pool Threads

By introducing these types of threads in detail, we aim to help developers understand their features and usage methods in depth, so as to make better choices in actual development, and solve the problem of vague concepts of certain threads.

2. User Threads

2.1 Definition

User threads, also known as foreground threads, are threads explicitly created and managed by applications. This type of thread is often used to perform tasks that require long-term running or interact with users. The life cycle of a user thread is completely controlled by the application and ends only when the thread completes its task or is explicitly terminated.

2.2 How to use

In C#, you can passClass creates user thread. Here is a simple example:

using System;
using ;
class Program
{
    static void Main()
    {
        Thread userThread = new Thread(new ThreadStart(UserThreadMethod));
        ();
        ("The main thread continues to execute...");
        (); // Wait for the user thread to complete        ("The main thread has been executed.");
    }
    static void UserThreadMethod()
    {
        ("The user thread starts executing...");
        (5000); // Simulate long-term tasks        ("The user thread has completed execution.");
    }
}

In the above code,ThreadObject passedThreadStartDelegate to specify the method to be executed and callStart()Method starts the thread.

2.3 Application scenarios

User threads are suitable for the following scenarios:

  • Long-running tasks: Such as file download, large-scale data processing or complex calculations.

  • Operations that require interaction with users: Such as background tasks in GUI applications to ensure that the user experience is not affected.

  • Needs precise control of thread life cycle: Developers need to explicitly manage the start, pause and termination of threads.

2.4 Features

  • life cycle: Controlled by the application until the thread completes the task or is terminated.

  • Priority: Can be passedProperties setting priority (e.g.) to adjust the execution order.

  • Resource consumption: Each user thread needs to allocate independent stack space and other system resources, and the creation and destruction cost is high.

3. Daemon Threads

3.1 Definition

Daemon threads, also known as background threads (Background Threads), are threads that run in the background and are usually used to perform auxiliary or supportive tasks. The life cycle of a daemon thread is closely related to the survival status of all user threads in the application: when all user threads terminate, the daemon thread is automatically terminated by the CLR regardless of whether its task is completed or not.

3.2 How to use

In C#, you can use it toThreadThe object'sIsBackgroundThe property is set totrueTo create a daemon thread. Here is an example:

using System;
using ;
class Program
{
    static void Main()
    {
        Thread daemonThread = new Thread(new ThreadStart(DaemonThreadMethod));
         = true; // Set as daemon thread        ();
        ("The main thread is executing...");
        (1000); // The main thread runs briefly        ("The main thread has been executed.");
    }
    static void DaemonThreadMethod()
    {
        while (true)
        {
            ("The daemon thread is running...");
            (500);
        }
    }
}

In the above code, when the main thread ends, the daemon thread will automatically terminate, even if itwhileThe loop has not been completed.

3.3 Application scenarios

Daemon threads are suitable for the following scenarios:

  • Auxiliary tasks: Such as logging, system monitoring or garbage collection.

  • Tasks that do not require explicit termination: When the application exits, the task can be safely aborted.

  • Resource Cleanup: Perform some non-critical cleanup operations before the application is closed.

3.4 Features

  • life cycle: Depend on user threads and terminates automatically when all user threads end.

  • Priority: Usually set to a lower priority (e.g.) to avoid interfering with front-end tasks.

  • Resource consumption: Similar to user threads, but due to their auxiliary nature, they usually do not carry core logic.

4. Main Thread

4.1 Definition

The main thread is a thread automatically created by the CLR when the application starts, and is responsible for executing the program's entry point (usuallyMainmethod). In C#, the main thread is essentially a user thread, but is classified separately due to its special status. The termination of the main thread usually marks the exit of the application.

4.2 How to use

The main thread does not need to be explicitly created by the developer and is directly managed by the CLR. Here is a simple example:

using System;
class Program
{
    static void Main()
    {
        ("The main thread starts executing...");
        (2000); // Simulate some work        ("The main thread has been executed.");
    }
}

In GUI applications such as Windows Forms or WPF, the main thread is also responsible for handling UI event loops.

4.3 Application scenarios

The main thread is suitable for the following scenarios:

  • Application entry point: Execute the initialization logic of the program.

  • GUI Application: Handle user interface events such as button clicks or window refresh.

  • Control program life cycle: The end of the main thread usually causes the application to exit.

4.4 Features

  • life cycle: From the program start toMainThe method is executed.

  • Priority: The default setting is normal priority ()。

  • Resource consumption: Similar to ordinary user threads, but automatically managed by CLR.

5. Worker Threads

5.1 Definition

Worker threads are threads created to perform specific tasks and are usually managed by thread pools, but can also be created manually. This type of thread is suitable for short, independent calculations or operations, and its life cycle is usually short. A worker thread can be a user thread or a daemon thread, depending on how it is created and configured.

5.2 How to use

In C#, you can passMethod to quickly create worker threads. Here is an example:

using System;
using ;
class Program
{
    static void Main()
    {
        (WorkerThreadMethod, "Task Data");
        ("The main thread continues to execute...");
        (2000); // Wait for the worker thread to complete    }
    static void WorkerThreadMethod(object state)
    {
        ($"Worker thread execution,state:{state}");
        (1000); // Simulation tasks        ("Work thread completed.");
    }
}

5.3 Application scenarios

Worker threads are suitable for the following scenarios:

  • Short mission: Such as asynchronous file reading, parallel computing or network request.

  • No complex management required: The thread pool will automatically handle the creation and destruction of threads.

  • Improve responsiveness: Move time-consuming operations from the main thread to the worker thread to keep the UI smooth.

5.4 Features

  • life cycle: managed by the thread pool. After the task is completed, the thread returns to the pool to be reused.

  • Priority: Usually normal priority.

  • Resource consumption: Reuse threads through thread pools, significantly reducing the overhead of creation and destruction.

6. Thread Pool Threads in thread pool

6.1 Definition

Threads in a thread pool are collections of threads managed by CLRs for efficient execution of asynchronous or parallel tasks. Thread pools improve performance and resource utilization by maintaining a thread cache pool to avoid frequent creation and destruction of threads.

6.2 How to use

C# providesThreadPoolClass to use thread pool threads. Here is an example:

using System;
using ;
class Program
{
    static void Main()
    {
        (ThreadPoolMethod, "Thread pool task");
        ("The main thread continues to execute...");
        (2000);
    }
    static void ThreadPoolMethod(object state)
    {
        ($"Thread pool thread execution,state:{state}");
        (1000);
        ("Thread pool thread completion.");
    }
}

In addition, modern C# can also be usedTaskClasses (based on thread pools) implement more advanced asynchronous programming:

using System;
using ;
class Program
{
    static async Task Main()
    {
        await (() => ("Task execution in thread pool"));
        ("The main thread continues to execute...");
    }
}

6.3 Application scenarios

Threads in thread pools are suitable for the following scenarios:

  • High concurrency tasks: For example, the web server handles multiple client requests.

  • Short and frequent tasks: Such as timer callback, asynchronous I/O operation.

  • Automatic resource management: Developers do not need to manually manage thread lifecycles.

6.4 Features

  • life cycle: Dynamically managed by CLR, and the thread returns to the pool after the task is completed.

  • Priority: The default normal priority can be adjusted through configuration.

  • Resource consumption: The thread pool dynamically adjusts the number of threads according to the system load and optimizes resource usage.

7. Comparison of thread types

The following table summarizes the key differences between the five thread types:

Thread type life cycle Priority Resource consumption Application scenarios
User thread Controlled by the application Can be set Higher Long-term tasks, user interaction
Daemon thread Automatically terminates as the user thread ends Usually lower medium Auxiliary tasks and resource cleaning
Main thread The program starts toMainFinish normal medium Program entry and GUI event handling
Worker thread Managed by thread pool, return after task normal Lower Short tasks, asynchronous operations
Threads in thread pool CLR dynamic management, thread reuse normal lowest High concurrency, frequent tasks

8. Conclusion

The thread types in C# each have their own unique functions and applicable scenarios:

  • User threads are suitable for long-term tasks that require precise control;

  • Daemon threads are suitable for background assisted work;

  • The main thread is the core driving force of the application;

  • Worker threads and threads in thread pools perform well when handling short, highly concurrent tasks.

Developers should choose the appropriate thread type according to specific needs, and combine thread synchronization, exception handling and other technologies to ensure the robustness and efficiency of the application. Through in-depth understanding and flexible use of these thread types, the performance and user experience of C# applications can be significantly improved.

References

  • Threading in C#:/en-us/dotnet/csharp/programming-guide/concepts/threading/

  • C# Threading Tutorial:/csharp/csharp_multithreading.htm

  • Understanding Threads in .NET:/article/understanding-threads-in-net/

This article about the essence of C# multi-threading programming: The theory of performance evolution from user threads to thread pools is introduced here. For more related C# multi-threading programming content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!