C# - 多线程

C# - 多线程 首页 / C#入门教程 / C# - 多线程

线程是轻量级进程,使用线程的一个常见示例是由现代操作系统实现并发编程,使用线程可以节省CPU周期的浪费并提高应用程序的效率。

到目前为止,无涯教程已经编写了程序,其中单个线程作为单个进程运行,这是应用程序的运行实例。但是,通过这种方式,应用程序可以一次执行一项工作。为了使其一次执行多个任务,可以将其划分为较小的线程。

生命周期

线程的生命周期在创建System.Threading.Thread类的对象时开始,在线程终止或完成执行时结束。

以下是线程-生命周期中的各种状态

  • The Unstarted State        - 在创建线程实例但未调用Start方法的情况下。

  • The Ready State               - 当线程准备运行并等待CPU周期时就是这种情况。

  • The Not Runnable State -  线程不可执行

    • Sleep 方法已被调用
    • Wait  方法已被调用
    • I/O操作阻塞
  • The Dead State                 - 线程完成执行或中止时的情况。

主线程

在C#中,System.Threading.Thread类用于处理线程,它允许在多线程应用程序中创建和访问各个线程,在进程中执行的第一个线程称为主线程。

当C#程序开始执行时,将自动创建主线程。使用Thread类创建的线程称为主线程的子线程。您可以使用Thread类的CurrentThread属性访问线程。

下面的程序演示了主线程执行-

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

属性和方法

下表显示了线程类-的一些最常用的属性

Sr.No.Property & 描述
1

CurrentContext

获取线程正在其中执行的当前上下文。

2

CurrentCulture

获取或设置当前线程的区域性。

3

CurrentPrinciple

获取或设置线程的当前主体(用于基于角色的安全性)。

4

CurrentThread

获取当前正在运行的线程。

5

CurrentUICulture

获取或设置资源管理器用于在运行时查找区域性特定资源的当前区域性。

6

ExecutionContext

获取一个ExecutionContext对象,该对象包含有关当前线程的各种上下文的信息。

7

IsAlive

获取一个值,该值指示当前线程的执行状态。

8

IsBackground

获取或设置一个值,该值指示线程是否为后台线程。

9

IsThreadPoolThread

获取一个值,该值指示线程是否属于托管线程池。

无涯教程网

10

ManagedThreadId

获取当前托管线程的唯一标识符。

11

Name

获取或设置线程的名称。

12

Priority

获取或设置一个值,该值指示线程的计划优先级。

13

ThreadState

获取一个包含当前线程状态的值。

下表显示了线程类-的一些最常用的方法

Sr.No.Method & 描述
1

public void abort()

在调用它的线程中引发ThreadAbortException,以开始终止线程的过程,调用此方法通常会终止线程。

2

public static LocalDataStoreSlot AllocateDataSlot()

在所有线程上分配一个未命名的数据槽,为了获得更好的性能,请改用ThreadStaticAttribute属性标签的字段。

3

public static LocalDataStoreSlot AllocateNamedDataSlot(string name)

在所有线程上分配命名数据槽,为了获得更好的性能,请改用ThreadStaticAttribute属性标签的字段。

4

public static void BeginCriticalRegion()

通知宿主执行即将进入一个代码区域,其中线程中止或未处理异常的影响可能会危及应用程序域中的其他任务。

5

public static void BeginThreadAffinity()

通知宿主托管代码即将执行取决于当前物理操作系统线程标识的指令。

6

public static void EndCriticalRegion()

通知宿主执行即将进入一个代码区域,其中线程中止或未处理异常的影响仅限于当前任务。

7

public static void EndThreadAffinity()

通知宿主托管代码已完成执行依赖于当前物理操作系统线程标识的指令。

8

public static void FreeNamedDataSlot(string name)

对于进程中的所有线程,消除名称和插槽之间的关联。为了获得更好的性能,请改用ThreadStaticAttribute属性标签的字段。

9

public static Object GetData(LocalDataStoreSlot Slot)

从当前线程的当前域内当前线程上的指定槽中检索值。为了获得更好的性能,请改用ThreadStaticAttribute属性标签的字段。

10

public static AppDomain GetDomain()

返回当前线程正在运行的当前域。

11

public static AppDomain GetDomainID()

返回唯一的应用程序域标识符

12

public static LocalDataStoreSlot GetNamedDataSlot(string name)

查找命名数据槽。为了获得更好的性能,请改用ThreadStaticAttribute属性标签的字段。

13

public void interrupt()

中断处于WaitSleepJoin线程状态的线程。

14

public void join()

阻塞调用线程,直到线程终止,同时继续执行标准COM和SendMessage抽水。此方法具有不同的重载形式。

15

public static void MemoryBarrier()

按如下方式同步内存访问:执行当前线程的处理器不能以这样的方式重新排序指令,即在调用MemoryBarrier之前的内存访问在调用MemoryBarrier之后的内存访问之后执行。

16

public static void ResetAbort()

取消为当前线程请求的中止。

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()

链接:https://www.learnfk.comhttps://www.learnfk.com/csharp/csharp-multithreading.html

来源:LearnFk无涯教程网

使调用线程将执行让给另一个准备在当前处理器上运行的线程。操作系统选择要向其屈服的线程。

创建线程

线程是通过扩展Thread类来创建的。然后,Extended Thread类调用start()方法开始执行子线程。

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

管理线程

下面的示例演示如何使用sleep()方法使线程暂停一段特定的时间。

using System;
using System.Threading;

namespace MultithreadingApplication {
   class ThreadCreationProgram {
      public static void CallToChildThread() {
         Console.WriteLine("Child thread starts");
         
         //the thread is paused for 5000 milliseconds
         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

销毁线程

运行库通过引发ThreadAbortException中止线程,无法捕获此异常,控制将发送到final块(如果有)。

using System;
using System.Threading;

namespace MultithreadingApplication {
   class ThreadCreationProgram {
      public static void CallToChildThread() {
         try {
            Console.WriteLine("Child thread starts");
            
            //do some work, like counting to 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();
         
         //stop the main thread for some time
         Thread.Sleep(2000);
         
         //now abort the child
         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 

祝学习愉快!(内容编辑有误?请选中要编辑内容 -> 右键 -> 修改 -> 提交!)

技术教程推荐

消息队列高手课 -〔李玥〕

Go 并发编程实战课 -〔晁岳攀(鸟窝)〕

etcd实战课 -〔唐聪〕

流程型组织15讲 -〔蒋伟良〕

如何落地业务建模 -〔徐昊〕

程序员的个人财富课 -〔王喆〕

林外 · 专利写作第一课 -〔林外〕

Kubernetes入门实战课 -〔罗剑锋〕

AI大模型之美 -〔徐文浩〕

好记忆不如烂笔头。留下您的足迹吧 :)