C#多线程之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");
  }

输出结果:

将上诉代码中的 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#多线程之线程控制详解

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

(0)

相关推荐

  • c#线程Thread示例

    C#是一门支持多线程的语言,因此线程的使用也是比较常见的.由于线程的知识在Win32编程的时候已经说得过多,所以在.Net中很少介绍这部分(可能.Net不觉得这部分是它所特有的). 那么线程相关的问题大致有如下四类(这篇文章只讨论单线程.单线程与UI线程这两方面的问题).问题一,线程的基本操作,例如:暂停.继续.停止等:问题二,如何向线程传递参数或者从中得到其返回值:问题三,如何使线程所占用的CPU不要老是百分之百:最后一个,也是问题最多的,就是如何在子线程来控制UI中的控件,换句话说,就是在线

  • C#多线程之Thread中Thread.IsAlive属性用法分析

    本文实例讲述了C#多线程之Thread中Thread.IsAlive属性用法.分享给大家供大家参考.具体如下: Thread.IsAlive属性 ,表示该线程当前是否为可用状态 如果线程已经启动,并且当前没有任何异常的话,则是true,否则为false Start()后,线程不一定能马上启动起来,也许CPU正在忙其他的事情,但迟早是会启动起来的! Thread oThread = new Thread(new ThreadStart(Back.Start)); oThread.Start();

  • 详解C#中 Thread,Task,Async/Await,IAsyncResult的那些事儿

    说起异步,Thread,Task,async/await,IAsyncResult 这些东西肯定是绕不开的,今天就来依次聊聊他们 1.线程(Thread) 多线程的意义在于一个应用程序中,有多个执行部分可以同时执行:对于比较耗时的操作(例如io,数据库操作),或者等待响应(如WCF通信)的操作,可以单独开启后台线程来执行,这样主线程就不会阻塞,可以继续往下执行:等到后台线程执行完毕,再通知主线程,然后做出对应操作! 在C#中开启新线程比较简单 static void Main(string[]

  • C#中Forms.Timer、Timers.Timer、Threading.Timer的用法分析

    本文实例讲述了C#中Forms.Timer.Timers.Timer.Threading.Timer的用法分析,分享给大家供大家参考.具体分析如下: 在.NET Framework里面提供了三种Timer ① System.Windows.Forms.Timer ② System.Timers.Timer ③ System.Threading.Timer 现分述如下: 一.System.Windows.Forms.Timer 1.基于Windows消息循环,用事件方式触发,在界面线程执行:是使用

  • C#多线程ThreadPool线程池详解

    简单说明一下: 线程池可以看做容纳线程的容器:一个应用程序最多只能有一个线程池:ThreadPool静态类通过QueueUserWorkItem()方法将工作函数排入线程池: 每排入一个工作函数,就相当于请求创建一个线程: 线程池的作用: 1.线程池是为突然大量爆发的线程设计的,通过有限的几个固定线程为大量的操作服务,减少了创建和销毁线程所需的时间,从而提高效率. 2.如果一个线程的时间非常长,就没必要用线程池了(不是不能作长时间操作,而是不宜.),况且我们还不能控制线程池中线程的开始.挂起.和

  • C#多线程之Thread中Thread.Join()函数用法分析

    本文实例讲述了C#多线程之Thread中Thread.Join()函数用法.分享给大家供大家参考.具体分析如下: Thread.Join()在MSDN中的解释:Blocks the calling thread until a thread terminates 当NewThread调用Join方法的时候,MainThread就被停止执行, 直到NewThread线程执行完毕. Thread oThread = new Thread(new ThreadStart(oAlpha.Beta));

  • C#利用System.Threading.Thread.Sleep即时输出信息的详解

    有个网站需要生成静态页.据以往经验,凡比较烂的空间,短时间内运行耗能大的运算,都会出现"service unavailable",以致网页无法正常打开.生成静态页,需要在短时间内读取大量的数据并保存为html页,好一些的空间运行起来没问题,就怕那些垃圾空间--生成的时候,需要即时输出信息通知客户. 根据经验思考后,有两种方法可行:1.每次只执行生成一个html页,然后输出信息给客户看,如"已生成首页,正在生成新闻页,请稍候..",然后在输出的代码里放置上js代码,j

  • C#多线程之Thread类详解

    使用System.Threading.Thread类可以创建和控制线程. 常用的构造函数有: // 摘要: // 初始化 System.Threading.Thread 类的新实例,指定允许对象在线程启动时传递给线程的委托. // // 参数: // start: // System.Threading.ParameterizedThreadStart 委托,它表示此线程开始执行时要调用的方法. // // 异常: // System.ArgumentNullException: // star

  • Java并发编程之LockSupport类详解

    一.LockSupport类的属性 private static final sun.misc.Unsafe UNSAFE; // 表示内存偏移地址 private static final long parkBlockerOffset; // 表示内存偏移地址 private static final long SEED; // 表示内存偏移地址 private static final long PROBE; // 表示内存偏移地址 private static final long SEC

  • Java并发编程之Executors类详解

    一.Executors的理解 Executors类属于java.util.concurrent包: 线程池的创建分为两种方式:ThreadPoolExecutor 和 Executors: Executors(静态Executor工厂)用于创建线程池: 工厂和工具方法Executor , ExecutorService , ScheduledExecutorService , ThreadFactory和Callable在此包中定义的类: jdk1.8API中的解释如下: 二.Executors

  • Java中Thread类详解及常用的方法

    目录 一.Thread 的常见构造方法 二.Thread 的常见属性 三.创建线程 四.中断线程 五.线程等待 六.获取线程引用 七.线程休眠 八.线程状态 总结 一.Thread 的常见构造方法 方法 说明 Thread() 创建线程对象 Thread(Runnable target) 使用 Runnable 对象创建线程对象 Thread(String name) 创建线程对象并命名 Thread(Runnable target,String name) 使用 Runnable 对象创建线程

  • C#线程开发之System.Thread类详解

    一.属性 CurrentContext    获取线程正在其中执行的当前上下文. ExecutionContext    获取 ExecutionContext 对象,该对象包含有关当前线程的各种上下文的信息. CurrentCulture    获取或设置当前线程的区域性. CurrentUICulture    获取或设置资源管理器使用的当前区域性以便在运行时查找区域性特定的资源. CurrentThread    获取当前正在运行的线程. IsAlive    获取指示当前线程的执行状态的

  • C#多线程之Semaphore用法详解

    Semaphore:可理解为允许线程执行信号的池子,池子中放入多少个信号就允许多少线程同时执行. private static void MultiThreadSynergicWithSemaphore() { //0表示创建Semaphore时,拥有可用信号量数值 //1表示Semaphore中,最多容纳信号量数值 Semaphore semaphore = new Semaphore(0, 1); Thread thread1 = new Thread(() => { //线程首先WaitO

  • Java多线程继承Thread类详解第1/2页

    调用方法: /** * 点击量/月(年)Thread */ public void yearlyClickThread() { // 获取参数 String year = getPara("year"); // 统计数据集X List<String> xList = new ArrayList<String>(); xList.add("January"); xList.add("February"); xList.add

  • Python 多线程其他属性以及继承Thread类详解

    一.线程常用属性 1.threading.currentThread:返回当前线程变量 2.threading.enumerate:返回一个包含正在运行的线程的list,正在运行的线程指的是线程启动后,结束前的状态 3.threading.activeCount:返回正在运行的线程数量,效果跟len(threading.enumer)一样 4.thr.setName:给线程设置名字 5.thr.getName:得到线程的名字. 举例: mport _thread as thread import

  • Java并发编程之Exchanger方法详解

    简介 Exchanger是一个用于线程间数据交换的工具类,它提供一个公共点,在这个公共点,两个线程可以交换彼此的数据. 当一个线程调用exchange方法后将进入等待状态,直到另外一个线程调用exchange方法,双方完成数据交换后继续执行. Exchanger的使用 方法介绍 exchange(V x):阻塞当前线程,直到另外一个线程调用exchange方法或者当前线程被中断. x : 需要交换的对象. exchange(V x, long timeout, TimeUnit unit):阻塞

  • Python多线程编程之threading模块详解

    一.介绍 线程是什么?线程有啥用?线程和进程的区别是什么? 线程是操作系统能够进行运算调度的最小单位.被包含在进程中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务. 二.Python如何创建线程 2.1 方法一: 创建Thread对象 步骤: 1.目标函数 2.实例化Thread对象 3.调用start()方法 import threading # 目标函数1 def fun1(num): for i in range(

随机推荐