SoFunction
Updated on 2025-03-06

Detailed explanation of C# thread development and other things

1. Attributes

  • CurrentContext    Gets the current context in which the thread is executing.
  • ExecutionContext    Gets an ExecutionContext object that contains information about various contexts of the current thread.
  • CurrentCulture    Get or set the culture of the current thread.
  • CurrentUICulture    Gets or sets the current culture used by the resource manager to find culture-specific resources at runtime.
  • CurrentThread   Get the currently running thread.
  • IsAlive   Gets the value indicating the execution status of the current thread.
  • IsBackground    Gets or sets a value that indicates whether a thread is a background thread.
  • IsThreadPoolThread   Gets the value indicating whether the thread belongs to the managed thread pool.
  • ManagedThreadId    Gets the unique identifier of the current managed thread.
  • Name   Get or set the name of the thread.
  • Priority    Gets or sets a value indicating the scheduling priority of the thread.
  • ThreadState    Gets a value that contains the status of the current thread.

2. Create and control threads

The constructor of the Thread class is overloaded to accept delegate parameters of ThreadStart and ParameterizedThreadStart types.
The ThreadStart delegate defines a parameterless method with a return type void. After creating the Thread object, you can start the thread using the Start() method:

class Program
{
    static void Main()
    {
        var t1 = new Thread(ThreadMain);
        ();
        ("This is the main thread.");
    }
    static void ThreadMain()
    {
        ("Running in a thread.");
    }
}

Lambda expressions can also be used with the Thread class to pass the implementation code of the thread method to the actual parameters of the Thread constructor:

static void Main()
{
    var t1 = new Thread(() => ("running in a thread, id: {0}",));
    ();
    ("This is the main thread, id: {0}",
    );
}

3. Pass parameters to threads

There are two ways to pass some data to a thread.

1. ParameterizedThreadStart delegation parameters

To pass data to threads, a class or structure that stores data is required. Here a Data structure containing strings is defined, but any object can be passed.

static void Main()
{
    var d = new Data { Message = "Info" };
    var t2 = new Thread(ThreadMainWithParameters);// ParameterizedThreadStart delegate instance    (d);
}
static void ThreadMainWithParameters(object o)//If the ParameterizedThreadStart delegate is used, the thread's entry point must have an object-type parameter and the return type is void.{
    Data d = (Data)o;
    ("Running in a thread, received {0}", );
}
public struct Data
{
    public string Message;
}

2. Create a custom class and define the thread's method as an instance method

Another way to pass data to a new thread is to define a class (see the MyThread class), where it defines the required fields, and defines the method called by the thread as an instance method of the class:

static void Main()
{
    var obj = new MyThread("info");
    var t3 = new Thread();//Instance method    ();
}
//Instance methodpublic class MyThread
{
    private string data;
    public MyThread(string data)
    {
         = data;
    }
    public void ThreadMain()
    {
        ("Running in a thread, data: {0}", data);
    }
}

4. Background thread

As long as there is a foreground thread running, the application's process is running.
If multiple foreground threads are running and the Main() method ends, the application's process is still activated until all foreground threads complete their tasks.
By default, threads created with the Thread class are foreground threads. The threads in the thread pool are always background threads.
When creating a thread with the Thread class, you can set the IsBackground property to determine whether the thread is a foreground thread or a background thread.

5. Priority of threads

In the Thread class, the Priority property can be set to affect the basic priority of the thread. The Priority property requires a value defined by the ThreadPriority enumeration. The defined levels are Highest, AboveNomal, BelowNormal, and Lowest.

6. Control thread

  • Call the Start() method of the Thread object to create a thread. However, after calling the Start() method, the new thread is still not in the Running state, but in the Unstarted state. As long as the operating system's thread scheduler selects the thread to be run, the thread will be changed to the Running state. Read Thread.ThreadStateattributes to obtain the current state of the thread.
  • Using the ThreadSleep() method will put the thread in the WaitSleepJoin state. After experiencing the time period defined by the Sleep() method, the thread will wait for it to be awakened again.
  • To stop another thread, you can call the() method. When this method is called, an exception of type ThreadAbortExceptim will be thrown in the thread that receives the termination command. By catching this exception with a handler, the thread can complete some cleansing work before it is finished. The thread can also continue to run after receiving the result of calling the() method ThreadAbortExcepdon exception. If the thread does not reset the termination, the status of the thread that received the termination request will be changed from AbortRequested to Aborted.
  • If you need to wait for the end of the thread, you can call the() method. The () method stops the current thread and sets it to the WaitSleepJoin state until the added thread completes.
public class Worker
{
    // This method will be called when the thread starts.    public void DoWork()
    {
        while (!_shouldStop)
        {
            ("Work thread: working...");
        }
        ("Work thread: Stopped normally");
    }
    public void RequestStop()
    {
        _shouldStop = true;
    }
    // Volatile is used to prompt the compiler that this data member will be accessed by multiple threads.    private volatile bool _shouldStop;
}

static void Main()
{
    // Create thread object, but this will not start the thread.    Worker workerObject = new Worker();
    Thread workerThread = new Thread();

    // Start the worker thread.    ();
    ("main thread: start worker thread...");

    // Loop until the worker thread is activated.    while (!) ;

    // Sleep the main thread for 1 millisecond, let the worker thread do some work:    (1);

    // Request the worker thread to stop itself:    ();//()

    // Use the Join method to block the current thread until the worker thread has completed execution and then execute it downward    ();
    ("main thread: The worker thread has been terminated.");
}

7. Use threads to implement callbacks

//Define a delegate implementation callback functionpublic delegate void CallBackDelegate(string message);

void Main()
{
    //Delegate implementation method and definition thread    CallBackDelegate cbd = CallBack;
    Thread thread = new Thread(initFtpParam);
    (cbd);
}

/// <summary>
/// Thread method/// </summary>
/// <param name="obj"></param>
public void initFtpParam(object obj)
{
    CallBackDelegate callBackDelegate = obj as CallBackDelegate;
    callBackDelegate("aa");//Execution of the delegation}

/// <summary>
/// Callback method/// </summary>
/// <param name="message"></param>
private void CallBack(string message)
{
    (message);
}

8. Regionality and threading

  • The CurrentUICulture property returns the current user interface culture. This property is used by the ResourceManager class to find culture-specific resources at runtime.
    The CurrentUICulture property can be set using non-specific cultures, specific cultures, or InvariantCulture.
    The default value is the operating system user interface language.
  • CurrentCulture attributes are used to determine how currency, numbers, and dates are formatted.
    The CurrentCulture property is not a language setting. It contains only data related to the standard settings of the geographic region. Therefore, you can only set the CurrentCulture property to a specific culture, such as "fr-FR" or InvariantCulture.
    The default value is the User Locale of the operating system, which we can set in the control panel. The attribute indicates whether to use the format of numbers, symbols, dates, currency, etc. that the user has customized in the control panel.

1. Before .NET 4.5, the following code can only be used to target a single thread. If you execute the thread, you must reset it every time. . .
A new thread is opened, and the default CurrentCulture is the system's Culture. If you want to change the Culture of the current thread, you need to modify the value in the thread to implement it.

 = new ("en-US");
 = new ("en-US");

2. If the .net environment used is 4.5 and above, CultureInfo provides two static properties DefaultThreadCulture and DefaultThreadUICulture. One modification can realize that all threads that are not explicitly set use this Default value.

 = new ("en-US");
 = new ("en-US");

This is all about this article about C# thread development. I hope it will be helpful to everyone's learning and I hope everyone will support me more.