热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C#多线程之Thread类详解

使用System.Threading.Thread类可以创建和控制线程。常用的构造函数有:摘要:初始化System.Threading.Thread类的新实例,指定

使用System.Threading.Thread类可以创建和控制线程。

常用的构造函数有:

 // 摘要: 
  //  初始化 System.Threading.Thread 类的新实例,指定允许对象在线程启动时传递给线程的委托。
  //
  // 参数: 
  // start:
  //  System.Threading.ParameterizedThreadStart 委托,它表示此线程开始执行时要调用的方法。
  //
  // 异常: 
  // System.ArgumentNullException:
  //  start 为 null。
  [SecuritySafeCritical]
  public Thread(ParameterizedThreadStart start);
  //
  // 摘要: 
  //  初始化 System.Threading.Thread 类的新实例。
  //
  // 参数: 
  // start:
  //  System.Threading.ThreadStart 委托,它表示此线程开始执行时要调用的方法。
  //
  // 异常: 
  // System.ArgumentNullException:
  //  start 参数为 null。
  [SecuritySafeCritical]
  public Thread(ThreadStart start);

1. 无参数创建线程

ThreadStart委托定义了一个返回类型位void的无参数方法。

public void Main()
  {
   Thread vThread = new Thread(ThreadFun);
   //vThread.Name = "td_Name"; // 线程名称
   vThread.Start(); //开始执行线程
   Console.WriteLine("This is the main thread:id=" + Thread.CurrentThread.ManagedThreadId);
  }

  void ThreadFun() // 来自委托:ThreadStart 
  {
   Console.WriteLine("Running in a new thread:id=" + Thread.CurrentThread.ManagedThreadId);
   for (int i = 0; i <10; i++)
   {
    Console.Write(".");
    Thread.Sleep(500);
   }
   Console.WriteLine("THREAD END");
  }

输出结果:

C#多线程之Thread类详解

将上诉代码中的 ThreadFun() 用Lambda表达式替换,变成Thread的简便使用方式:

 public void Main()
  {
   Thread vThread = new Thread(() =>
   {
    Console.WriteLine("Running in a new thread");
   });
   //vThread.Name = "td_Name"; // 线程名称
   vThread.Start(); //开始执行线程
   Console.WriteLine("This is the main thread");
  }

2.给线程传递参数

两种方式:一种是使用带ParameterizedThreadStart委托的方法参数构造Thread;另一种是创建一个自定义类,把线程的方法定义为实例方法,这样先初始化实例的数据,在启动线程。

如:传递参数

public struct TdData // 传递数据
  {
   public string Message; //数据string字段
  }

使用第一种方式:

 public void Main()
  {
   TdData tData = new TdData() { Message = "Thread Info" };
   Thread vThread = new Thread(ThreadFun);
   vThread.Start(tData); // 开始执行线程,传递参数
   Console.WriteLine("This is the main thread");
  }

  void ThreadFun(object pObj) // 来自委托:ParameterizedThreadStart 
  {
   TdData vData = (TdData)pObj;
   Console.WriteLine("In a new thread, Received:{0}", vData.Message);   
  }

使用第二种方式:先自定义一个类。

public class TdHelper
 {
  public TdData mData; // 传递数据

  // 构造函数
  public TdHelper(TdData pData)
  {
   this.mData = pData;
  }

  public void ThreadFun() // 来自委托:ThreadStart 
  {
   Console.WriteLine("In a new thread, TdDataMessage:{0}", mData.Message);
  }
 }

然后,在主线程(需要的地方)创建Thread并将实例方法TdHelper.ThreadFun()作为构造函数的参数。

public void Main()
  {
   TdData tData = new TdData() { Message = "Thread Info" };
   TdHelper tHelper = new TdHelper(tData); // 传递参数
   Thread vThread = new Thread(tHelper.ThreadFun);
   vThread.Start();
   Console.WriteLine("This is the main thread");
  }


3.后台线程

默认情况下,Thread类创建的线程事前台线程,线程池中的线程总是后台线程。只要有一个前台线程在运行,应用程序的进程就在运行,如果多个前台线程在运行,而Main()方法结束了,应用程序仍然事激活的,直到所有前台线程完成任务。

可以通过设置Thread类实例的IsBackground属性,来让其成为后台线程;

public void Main()
  {
   Thread vThread = new Thread(() =>
   {
    Console.WriteLine("New thread started"); // Title3
    Thread.Sleep(5000);
    Console.WriteLine("New thread completed"); // Title2
   });
   //vThread.IsBackground = true;
   vThread.Start();
   Console.WriteLine("This is the main thread"); // Title1
  }

 当IsBackground属性默认为false时,可以在控制台完整地看到 3 句输出信息;但如果将其设为true时,则不等到第3条信息(Title2)输出时,主线程Main()已经执行完成,控制台窗口就自动关闭了。

4.线程的优先级

通过Priority属性,可以调整Thread类实例的优先级,默认为: vThread.Priority = ThreadPriority.Normal; // 枚举值

关系:Highest > AboveNormal > Normal > BelowNormal > Lowest

5.控制线程

调用Thread对象的Start()方法,可以创建线程。但是,在调用Start()方法后,新线程仍不是处于 Running 状态,而是 Unstarted 状态。只有操作系统的线程调度器选择了要运行该线程,线程就会改为 Running 状态。通过 Thread.ThreadState 属性,可以获得该线程当前的状态。

使用Thread.Sleep()方法,会使线程处于WaitSleepJoin状态,在经历Sleep()方法定义的时间段后,线程就会等待再次被操作系统调度。

要停止一个线程,可以调用 Thread.Abort() 方法。调用这个方法,会在接到终止命令的线程中抛出一个 ThreadAbortException,用一个处理程序捕获这个异常,线程可以在结束前完成一些清理工作。线程还可以在接收到调用 Thread.Abort() 方法的结果 ThreadAbortException 异常后继续工作。如果线程没有重置终止,接收到终止请求的线程的状态就从 AbortRequested 改为 Aborted 。

如果要等待线程结束,就可以调用 Thread.Join() 方法,它会停止当前线程,并把它设置为 WaitSleepJoin 状态,直到加入的线程完成为止。

参见: C#多线程之线程控制详解

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程笔记。


推荐阅读
  • 本文深入探讨了C#中的反射与特性功能。首先,介绍了反射的基本概念,即通过元数据(包括类的方法、属性和字段等)在运行时动态获取和操作程序信息的能力。此外,还详细解析了特性的使用方法及其在代码注解和元数据扩展中的重要作用,为开发者提供了丰富的编程技巧和实践指导。 ... [详细]
  • 本文将继续探讨 JavaScript 函数式编程的高级技巧及其实际应用。通过一个具体的寻路算法示例,我们将深入分析如何利用函数式编程的思想解决复杂问题。示例中,节点之间的连线代表路径,连线上的数字表示两点间的距离。我们将详细讲解如何通过递归和高阶函数等技术实现高效的寻路算法。 ... [详细]
  • 在PHP中如何正确调用JavaScript变量及定义PHP变量的方法详解 ... [详细]
  • 本文是Java并发编程系列的开篇之作,将详细解析Java 1.5及以上版本中提供的并发工具。文章假设读者已经具备同步和易失性关键字的基本知识,重点介绍信号量机制的内部工作原理及其在实际开发中的应用。 ... [详细]
  • 在尝试对 QQmlPropertyMap 类进行测试驱动开发时,发现其派生类中无法正常调用槽函数或 Q_INVOKABLE 方法。这可能是由于 QQmlPropertyMap 的内部实现机制导致的,需要进一步研究以找到解决方案。 ... [详细]
  • DVWA学习笔记系列:深入理解CSRF攻击机制
    DVWA学习笔记系列:深入理解CSRF攻击机制 ... [详细]
  • 本指南介绍了如何在ASP.NET Web应用程序中利用C#和JavaScript实现基于指纹识别的登录系统。通过集成指纹识别技术,用户无需输入传统的登录ID即可完成身份验证,从而提升用户体验和安全性。我们将详细探讨如何配置和部署这一功能,确保系统的稳定性和可靠性。 ... [详细]
  • 优化后的标题:深入探讨网关安全:将微服务升级为OAuth2资源服务器的最佳实践
    本文深入探讨了如何将微服务升级为OAuth2资源服务器,以订单服务为例,详细介绍了在POM文件中添加 `spring-cloud-starter-oauth2` 依赖,并配置Spring Security以实现对微服务的保护。通过这一过程,不仅增强了系统的安全性,还提高了资源访问的可控性和灵活性。文章还讨论了最佳实践,包括如何配置OAuth2客户端和资源服务器,以及如何处理常见的安全问题和错误。 ... [详细]
  • C++ 异步编程中获取线程执行结果的方法与技巧及其在前端开发中的应用探讨
    本文探讨了C++异步编程中获取线程执行结果的方法与技巧,并深入分析了这些技术在前端开发中的应用。通过对比不同的异步编程模型,本文详细介绍了如何高效地处理多线程任务,确保程序的稳定性和性能。同时,文章还结合实际案例,展示了这些方法在前端异步编程中的具体实现和优化策略。 ... [详细]
  • Python 程序转换为 EXE 文件:详细解析 .py 脚本打包成独立可执行文件的方法与技巧
    在开发了几个简单的爬虫 Python 程序后,我决定将其封装成独立的可执行文件以便于分发和使用。为了实现这一目标,首先需要解决的是如何将 Python 脚本转换为 EXE 文件。在这个过程中,我选择了 Qt 作为 GUI 框架,因为之前对此并不熟悉,希望通过这个项目进一步学习和掌握 Qt 的基本用法。本文将详细介绍从 .py 脚本到 EXE 文件的整个过程,包括所需工具、具体步骤以及常见问题的解决方案。 ... [详细]
  • 当使用 `new` 表达式(即通过 `new` 动态创建对象)时,会发生两件事:首先,内存被分配用于存储新对象;其次,该对象的构造函数被调用以初始化对象。为了确保资源管理的一致性和避免内存泄漏,建议在使用 `new` 和 `delete` 时保持形式一致。例如,如果使用 `new[]` 分配数组,则应使用 `delete[]` 来释放内存;同样,如果使用 `new` 分配单个对象,则应使用 `delete` 来释放内存。这种一致性有助于防止常见的编程错误,提高代码的健壮性和可维护性。 ... [详细]
  • Web开发框架概览:Java与JavaScript技术及框架综述
    Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
  • 如何在C#中配置组合框的背景颜色? ... [详细]
  • 技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统
    技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统 ... [详细]
  • 【系统架构师精讲】(16):操作系统核心概念——寄存器、内存与缓存机制详解
    在计算机系统架构中,中央处理器(CPU)内部集成了多种高速存储组件,用于临时存储指令、数据和地址。这些组件包括指令寄存器(IR)、程序计数器(PC)和累加器(ACC)。寄存器作为集成电路中的关键存储单元,由触发器构成,具备极高的读写速度,使得数据传输非常迅速。根据功能不同,寄存器可分为基本寄存器和移位寄存器,各自在数据处理中发挥重要作用。此外,寄存器与内存和缓存机制的协同工作,确保了系统的高效运行。 ... [详细]
author-avatar
逍遥子
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有