Unity basic learning eighteen, C# multithreading

A thread is defined as a program's execution path. Each thread defines a unique flow of control. If your application involves complex and time-consuming operations, it is often beneficial to have different execution paths for threads, with each thread performing specific work.

Threads are lightweight processes . A common example of the use of threads is the implementation of parallel programming in modern operating systems. Using threads saves wasted CPU cycles and improves application efficiency .

1. Thread life cycle

The thread lifecycle begins when an object of the System.Threading.Thread class is created and ends when the thread is terminated or completes execution.

The various states in the thread lifecycle are listed below:

  • Not started state : The state when the thread instance is created but the Start method is not called.
  • Ready state : The state when a thread is ready to run and waiting for CPU cycles.
  • Non-runnable state : A thread is not runnable in the following situations:

    • The Sleep method has been called
    • The Wait method has been called
    • Blocking on I/O operations
  • Dead state : The condition when a thread has completed execution or has been aborted.

2. Main thread

In C#, the System.Threading.Thread class is used for thread work. It allows creation and access to individual threads in a multithreaded application. The first thread executed in a process is called the main thread

When a C# program starts executing, the main thread is created automatically. Threads created using the Thread class are called by sub-threads of the main thread. You can access threads using the CurrentThread property of the Thread class .

The following program demonstrates the execution of the main thread:

using System;
using System.Threading;

namespace MultithreadingApplication
{
    class MainThreadProgram
    {
        static void Main(string[] args)
        {
            Thread th = Thread.CurrentThread;
            th.Name = "MainThread";
            Console.WriteLine("This is {0}", th.Name);
            Console.ReadKey();
        }
    }
}
This is MainThread

3. Common properties and methods of the Thread class

The following table lists   some commonly used  properties of the Thread class :

CurrentContext Gets the current context in which the thread is executing.
CurrentCulture Gets or sets the culture of the current thread.
CurrentPrincipal Gets or sets the thread's current leader (for role-based security).
CurrentThread Get the currently running thread.
CurrentUICulture Gets or sets the current culture used by the resource manager to find culture-specific resources at runtime.
ExecutionContext Gets an ExecutionContext object that contains information about the current thread's various contexts.
IsAlive Gets a value indicating the execution state of the current thread.
IsBackground Gets or sets a value indicating whether a thread is a background thread.
IsThreadPoolThread Gets a value indicating whether the thread belongs to the managed thread pool.
ManagedThreadId Get the unique identifier for the currently managed thread.
Name Gets or sets the name of the thread.
Priority Gets or sets a value indicating the thread's scheduling priority.
ThreadState Gets a value containing the state of the current thread.

The following table lists   some commonly used  methods of the Thread class :

1 public void Abort()
Throws a ThreadAbortException on the thread calling this method to begin the process of terminating this thread. Calling this method normally terminates the thread.
2 public static LocalDataStoreSlot AllocateDataSlot()
allocates unnamed data slots on all threads. For better performance, use fields marked with the ThreadStaticAttribute attribute instead.
3 public static LocalDataStoreSlot AllocateNamedDataSlot( string name)
Allocates named data slots on all threads. For better performance, use fields marked with the ThreadStaticAttribute attribute instead.
4 public static void BeginCriticalRegion()
Notifies the host that execution is about to enter a region of code where a thread abort or the effects of an unhandled exception could jeopardize other tasks in the application domain.
5 public static void BeginThreadAffinity()
Notifies the host that managed code is about to execute instructions that depend on the identity of the current physical operating system thread.
6 public static void EndCriticalRegion()
Notifies the host that execution is about to enter a region of code where a thread abort or an unhandled exception affects only the current task.
7 public static void EndThreadAffinity()
Notifies the host that managed code has finished executing instructions that depend on the identity of the current physical operating system thread.
8 public static void FreeNamedDataSlot(string name)
removes the association between the name and the slot for all threads in the process. For better performance, use fields marked with the ThreadStaticAttribute attribute instead.
9 public static Object GetData( LocalDataStoreSlot slot )
retrieves the value from the specified slot on the current thread in the current domain of the current thread. For better performance, use fields marked with the ThreadStaticAttribute attribute instead.
10 public static AppDomain GetDomain()
Returns the current domain in which the current thread is running.
11 public static AppDomain GetDomainID()
returns the unique application domain identifier.
12 public static LocalDataStoreSlot GetNamedDataSlot( string name )
Finds a named data slot. For better performance, use fields marked with the ThreadStaticAttribute attribute instead.
13 public void Interrupt()
Interrupts a thread in the WaitSleepJoin thread state.
14 public void Join()
Blocks the calling thread until a thread terminates while continuing to perform standard COM and SendMessage message pumping. This method has different overloaded forms.
15 public static void MemoryBarrier()
synchronizes memory access as follows: when the processor executing the current thread reorders instructions, it cannot use the method of executing the memory access after the MemoryBarrier call first, and then executing the memory access before the MemoryBarrier call .
16 public static void ResetAbort()
Cancels the Abort requested for the current thread.
17 public static void SetData( LocalDataStoreSlot slot, Object data )
在当前正在运行的线程上为此线程的当前域在指定槽中设置数据。为了获得更好的性能,请改用以 ThreadStaticAttribute 属性标记的字段。
18 public void Start()
开始一个线程。
19 public static void Sleep( int millisecondsTimeout )
让线程暂停一段时间。
20 public static void SpinWait( int iterations )
导致线程等待由 iterations 参数定义的时间量。
21 public static byte VolatileRead( ref byte address )
public static double VolatileRead( ref double address )
public static int VolatileRead( ref int address )
public static Object VolatileRead( ref Object address )

读取字段值。无论处理器的数目或处理器缓存的状态如何,该值都是由计算机的任何处理器写入的最新值。此方法有不同的重载形式。这里只给出了一些形式。
22 public static void VolatileWrite( ref byte address, byte value )
public static void VolatileWrite( ref double address, double value )
public static void VolatileWrite( ref int address, int value )
public static void VolatileWrite( ref Object address, Object value )

立即向字段写入一个值,以使该值对计算机中的所有处理器都可见。此方法有不同的重载形式。这里只给出了一些形式。
23 public static bool Yield()
导致调用线程执行准备好在当前处理器上运行的另一个线程。由操作系统选择要执行的线程。

 4.创建线程

using System;
using System.Threading;

namespace MultithreadingApplication
{
    class ThreadCreationProgram
    {
        public static void CallToChildThread()
        {
            Console.WriteLine("Child thread starts");
        }
       
        static void Main(string[] args)
        {
            ThreadStart childref = new ThreadStart(CallToChildThread);
            Console.WriteLine("In Main: Creating the Child thread");
            Thread childThread = new Thread(childref);
            childThread.Start();
            Console.ReadKey();
        }
    }
}
In Main: Creating the Child thread
Child thread starts

5.管理线程

下面的实例演示了 sleep() 方法的使用,用于在一个特定的时间暂停线程。(程序在主线程中,就是暂停主线程,在副线程就是暂停副线程)

using System;
using System.Threading;

namespace MultithreadingApplication
{
    class ThreadCreationProgram
    {
        public static void CallToChildThread()
        {
            Console.WriteLine("Child thread starts");
            // 线程暂停 5000 毫秒
            int sleepfor = 5000;
            Console.WriteLine("Child Thread Paused for {0} seconds",
                              sleepfor / 1000);
            Thread.Sleep(sleepfor);
            Console.WriteLine("Child thread resumes");
        }
       
        static void Main(string[] args)
        {
            ThreadStart childref = new ThreadStart(CallToChildThread);
            Console.WriteLine("In Main: Creating the Child thread");
            Thread childThread = new Thread(childref);
            childThread.Start();
            Console.ReadKey();
        }
    }
}
In Main: Creating the Child thread
Child thread starts
Child Thread Paused for 5 seconds
Child thread resumes

6.销毁线程

Abort() 方法用于销毁线程。

通过抛出 threadabortexception 在运行时中止线程。这个异常不能被捕获,如果有 finally 块,控制会被送至 finally 块。

using System;
using System.Threading;

namespace MultithreadingApplication
{
    class ThreadCreationProgram
    {
        public static void CallToChildThread()
        {
            try
            {

                Console.WriteLine("Child thread starts");
                // 计数到 10
                for (int counter = 0; counter <= 10; counter++)
                {
                    Thread.Sleep(500);
                    Console.WriteLine(counter);
                }
                Console.WriteLine("Child Thread Completed");

            }
            catch (ThreadAbortException e)
            {
                Console.WriteLine("Thread Abort Exception");
            }
            finally
            {
                Console.WriteLine("Couldn't catch the Thread Exception");
            }

        }
       
        static void Main(string[] args)
        {
            ThreadStart childref = new ThreadStart(CallToChildThread);
            Console.WriteLine("In Main: Creating the Child thread");
            Thread childThread = new Thread(childref);
            childThread.Start();
            // 停止主线程一段时间
            Thread.Sleep(2000);
            // 现在中止子线程
            Console.WriteLine("In Main: Aborting the Child thread");
            childThread.Abort();
            Console.ReadKey();
        }
    }
}
In Main: Creating the Child thread
Child thread starts
0
1
2
In Main: Aborting the Child thread
Thread Abort Exception
Couldn't catch the Thread Exception 

引用

C# 多线程 | 菜鸟教程

Guess you like

Origin blog.csdn.net/u013617851/article/details/124576370