C# 多线程

  线程 被定义为程序的执行路径。每个线程都定义了一个独特的控制流。如果您的应用程序涉及到复杂的和耗时的操作,那么设置不同的线程执行路径往往是有益的,每个线程执行特定的工作。

  线程是轻量级进程。一个使用线程的常见实例是现代操作系统中并行编程的实现。使用线程节省了 CPU 周期的浪费,同时提高了应用程序的效率。

  到目前为止我们编写的程序是一个单线程作为应用程序的运行实例的单一的过程运行的。但是,这样子应用程序同时只能执行一个任务。为了同时执行多个任务,它可以被划分为更小的线程。

  线程生命周期

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

  下面列出了线程生命周期中的各种状态:

  未启动状态:当线程实例被创建但 Start 方法未被调用时的状况。

  就绪状态:当线程准备好运行并等待 CPU 周期时的状况。

  不可运行状态:下面的几种情况下线程是不可运行的:

  已经调用 Sleep 方法

  已经调用 Wait 方法

  通过 I/O 操作阻塞

  死亡状态:当线程已完成执行或已中止时的状况。

  主线程

  在 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

  Thread 类常用的属性和方法

  下表列出了 Thread 类的一些常用的 属性:

  属性描述

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

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

  CurrentPrinciple获取或设置线程的当前负责人(对基于角色的安全性而言)。

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

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

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

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

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

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

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

  Name获取或设置线程的名称。

  Priority获取或设置一个值,该值指示线程的调度优先级。

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

  下表列出了 Thread 类的一些常用的 方法:

  序号方法名 & 描述

  1public void Abort()

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

  2public static LocalDataStoreSlot AllocateDataSlot()

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

  3public static LocalDataStoreSlot AllocateNamedDataSlot( string name)

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

  4public static void BeginCriticalRegion()

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

  5public static void BeginThreadAffinity()

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

  6public static void EndCriticalRegion()

  通知主机执行将要进入一个代码区域,在该代码区域内线程中止或未经处理的异常仅影响当前任务。

  7public static void EndThreadAffinity()

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

  8public static void FreeNamedDataSlot(string name)

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

  9public static Object GetData( LocalDataStoreSlot slot )

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

  10public static AppDomain GetDomain()

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

  11public static AppDomain GetDomainID()

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

  12public static LocalDataStoreSlot GetNamedDataSlot( string name )

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

  13public void Interrupt()

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

  14public void Join()

  在继续执行标准的 COM 和 SendMessage 消息泵处理期间,阻塞调用线程,直到某个线程终止为止。此方法有不同的重载形式。

  15public static void MemoryBarrier()

  按如下方式同步内存存取:执行当前线程的处理器在对指令重新排序时,不能采用先执行 MemoryBarrier 调用之后的内存存取,再执行 MemoryBarrier 调用之前的内存存取的方式。

  16public static void ResetAbort()

  取消为当前线程请求的 Abort。

  17public static void SetData( LocalDataStoreSlot slot, Object data )

  在当前正在运行的线程上为此线程的当前域在指定槽中设置数据。为了获得更好的性能,请改用以 ThreadStaticAttribute 属性标记的字段。

  18public void Start()

  开始一个线程。

  19public static void Sleep( int millisecondsTimeout )

  让线程暂停一段时间。

  20public static void SpinWait( int iterations )

  导致线程等待由 iterations 参数定义的时间量。

  21public 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 )

  读取字段值。无论处理器的数目或处理器缓存的状态如何,该值都是由计算机的任何处理器写入的最新值。此方法有不同的重载形式。这里只给出了一些形式。

  22public 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 )

  立即向字段写入一个值,以使该值对计算机中的所有处理器都可见。此方法有不同的重载形式。这里只给出了一些形式。

  23public static bool Yield()

  导致调用线程执行准备好在当前处理器上运行的另一个线程。由操作系统选择要执行的线程。

  创建线程

  线程是通过扩展 Thread 类创建的。扩展的 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

  管理线程

  Thread 类提供了各种管理线程的方法。

  下面的实例演示了 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

  销毁线程

  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

  本文转载自:w3cschool

  (编辑:雷林鹏 来源:网络)

雷林鹏分享:C# 多线程的更多相关文章

  1. 雷林鹏分享:Ruby 多线程

    Ruby 多线程 每个正在系统上运行的程序都是一个进程.每个进程包含一到多个线程. 线程是程序中一个单一的顺序控制流程,在单个程序中同时运行多个线程完成不同的工作,称为多线程. Ruby 中我们可以通 ...

  2. 雷林鹏分享: C# 简介

    C# 简介 C# 是一个现代的.通用的.面向对象的编程语言,它是由微软(Microsoft)开发的,由 Ecma 和 ISO 核准认可的. C# 是由 Anders Hejlsberg 和他的团队在 ...

  3. 雷林鹏分享:Ruby Socket 编程

    Ruby Socket 编程 Ruby提供了两个级别访问网络的服务,在底层你可以访问操作系统,它可以让你实现客户端和服务器为面向连接和无连接协议的基本套接字支持. Ruby 统一支持应用程的网络协议, ...

  4. 雷林鹏分享:CodeIgniter 数据库操作

    在平时项目开发过程中,除了处理那些繁琐的逻辑过程外,还有一个重要的任务就是对数据库的操作处理.这里总结下自己平时使用CI过程中使用的如何对数据库进行操作处理. 在CI框架中,我们一般会把对数据库的操作 ...

  5. 雷林鹏分享:YAF路由问题

    这2天休年假,在家宅着学习研究了YAF框架,用YAF做过APP接口的项目,但是没有用来做过WEB方面的应用.趁着这2天在家想把博客用YAF进行一下改版,目的也想进一步学习一下YAF. 在这过程中遇到不 ...

  6. 雷林鹏分享:url中加号引发的错误

    刚发现了博客的一个bug,标签页中一些标签带有空格,在url输出中使用了 urlencode 函数进行处理,导致空格被转换成了加号(+),这时通过url访问时会出现错误: 临时解决方法是在urlcod ...

  7. 雷林鹏分享:Composer 安装

    下午在安装 Laravel 框架过程中,遇到了不少问题,因为 Laravel 的安装依赖于 composer,这里就先介绍一下 composer 的安装方法: 安装方法: #下载 sudo curl ...

  8. 雷林鹏分享:Laravel 安装

    前面我们介绍我了 composer安装,这里我们接着来介绍 Laravel框架的安装. 这里我们安装的是laravel 4 项目下载地址:https://github.com/laravel/lara ...

  9. 雷林鹏分享:CodeIgniter常用的数据库操作类

    在 CodeIgniter 中,使用数据库是非常频繁的事情.你可以使用框架自带的数据库类,就能便捷地进行数据库操作. 初始化数据库类 依据你的数据库配置载入并初始化数据库类: $this->lo ...

随机推荐

  1. GCC编译器ABI

    ABI与EABI 1)ABI(Application Binary Interface for the ARM Architecture),描述了应用程序与cpu内核的低级接口. ABI允许编译好的目 ...

  2. 人生苦短之我用Python篇(socket编程)

    socket模块 实现简单的远程连接: 客户端: import socket client = socket.socket()#声明socket类型,同时生成socke连接t对象 client.con ...

  3. EditPlus 5.1.2066 中文版(1月30日修正)

    之前有一些网友反馈汉化版的 EditPlus 中翻页键无法正常工作.经过调查,发现是翻译工具的问题. 因此,我用新的工具重新翻译了 EditPlus.翻页键在新中文版中应该可以正常工作了. 有需要的网 ...

  4. 01: 安装zabbix server

    目录:Django其他篇 01: 安装zabbix server 02:zabbix-agent安装配置 及 web界面管理 03: zabbix API接口 对 主机.主机组.模板.应用集.监控项. ...

  5. 01: awk常用

    1.1 awk基本使用 1.找出当前登录用户数量 [root@localhost ~]# w 14:09:07 up 48 min, 2 users, load average: 0.00, 0.01 ...

  6. 10:Python2与Python3比较

    1.print 函数 1. print语句没有了,取而代之的是print()函数. Python 2.6与Python 2.7部分地支持这种形式的print语法. 2.Unicode 1.  在pyt ...

  7. 实现windows命令提示符的tab补全

    1:使用win+r打开 运行 控制台 2:输入 regedit 打开注册表 3:进入 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor\C ...

  8. 20165310java_teamExp1_week1

    结对编程项目-四则运算-week1 需求分析 第一周达成 支持真分数的四则运算 支持多运算符 能手动输入n道题目,n由使用者输入 后续拓展的可能 能随机生成n道题目,n由使用者输入 能够判断正误,错误 ...

  9. sql注入学习心得与sqlmap使用心得

    做题是最好的老师 首先先来分享一下我用来练手的题目,实验吧中的简单的sql注入1,2,3 不得不说,sql注入真是一个神奇的东西,至少我以前看起来一点头绪都没有的题目能入手了 首先是简单的sql注入3 ...

  10. CSS实现三角形、梯形、平行四边形、圆形、椭圆形、对话框、自适应正方形

    本文篇幅较长,希望能坚持看完,转载请注明出处,如果觉得好文请给个赞吧 CSS实现梯形 CSS实现三角形和梯形主要是依靠border是梯形的特性来做的,有点像相框的那种感觉. 首先我们先给一个正方形设置 ...