Thread类可以创建和控制线程,Thread类的构造函数重载为接受ThreadStart和ParameterizedThreadStart类型的委托参数。下面我们用一个例子来解释怎样用Thread类来创建一个简单的线程

  1. static void Main(string[] args)
  2. {
  3. #region Thread无参数举例
  4. Thread th = new Thread(ThreadChild);
  5. th.Start();
  6. Console.WriteLine("Main Thread Start!");
  7. #endregion
  8. }
  9. static void ThreadChild()
  10. {
  11. Console.WriteLine("Child Thread Start!");
  12. }

输出结果

  程序运行的结果不能保证哪个先输出,因为线程是由操作系统调度,每次哪个线程在前面可以不同

给线程传递数据

  

  上面的例子演示了怎样用Thread类来创建一个不带传参的线程,下面我门来创建一个带传入参数的线程。给线程传递参数,有两种方式,一种是使用带ParameterizedThreadStart委托参数的Thread的构造函数,另外一种是定义一个自定义类。首先我们使用ParameterizedThreadStart委托来创建有传入参数的类。使用ParameterizedThreadStart,线程的入口(线程调用的方法)必须有一个Object类型的参数,使用Object我们首先想到的就是类型不安全。而且在执行线程的时候多半有装箱拆箱操作。管它的,我们先用这种方式来创建一个带传入参数的线程!!

  废话再多,还是没有直接上代码来得实在,看代码!!

  1. static void Main(string[] args)
  2. {
  3. #region 使用parameterizedThreadStart委托执行带参数的委托
  4. Thread th2 = new Thread(Thread_param);
  5. th2.Start(20);
  6. #endregion
  7. }
  8. static void Thread_param(object msg)
  9. {
  10. int message = (int)msg;
  11. Console.WriteLine("Result:{0}",message);
  12. }

运行结果

  

上面创建的线程是类型不安全的,那用什么样的方式执行带传入参数的线程的方法是类型安全的呢,答案就是创建一个自定义类,在类中定义一个作为传入参数的字段,将线程的主方法定义为一个类的实例方法。然而使用这种方法就可以使用泛型来解决使用ParameterizedThreadStart的类型不安全

看招!!!!

  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. #region 使用自定义类实现带参数的线程
  6. MyThread<string> mythread = new MyThread<string>("Thread_child");
  7. Thread th3 = new Thread(mythread.ThreadChild);
  8. th3.Start();
  9. #endregion
  10. }
  11. }
  12. class MyThread<T>
  13. {
  14. private T data;
  15. public MyThread(T data)
  16. {
  17. this.data = data;
  18. }
  19. public void ThreadChild()
  20. {
  21. Console.WriteLine("Child Thread Start! Result:{0}",data);
  22. }
  23. }

运行结果:

后台线程  

  Thread类默认创建的是前台线程,所以我们前面创建的线程全部都是前台线程。只要有一个前台线程在运行,应用程序的进程就在运行。如果有多个前台线程在运行,而Main()方法(主线程)结束了,应用程序的进程就仍然是激活的,直到所有前台线程完成其任务为止。

  那后台线程呢?显然和前台线程相反。当主线程结束后,应用程序的进程就终止了,在所有前台线程结束后,后台线程就会被终止。

  在编码的时候我们可以设置Thread类的IsBackground的属性来确定该线程是前台线程还是后台线程。当IsBackground设置为False的时候,为前台线程,设置为Ture的时候为后台线程,下面我们举例来说明前台线程和后台线程的区别。首先我们创建一个前台线程。

  1. static void Main(string[] args)
  2. {
  3. Thread th_pre = new Thread(Thread_pre)
  4. {Name="Thread_pre",IsBackground=flase};;
  5. th_pre.Start();
  6. Console.WriteLine("主线程执行完成!");
  7. }
  8. static void Thread_pre()
  9. {
  10. Console.WriteLine("子线程开始执行!");
  11. Thread.Sleep(3000);
  12. Console.WriteLine("子线程执行完成!");
  13. }

运行结果

  从上面的运行结果可以看到,当主线程执行完成后,应用程序终止前就会子线程执行完成。

  下面我们来看看后台线程,看代码!!

  1.      static void Main(string[] args)
  2. {
  3.        Thread th_back = new Thread(Thread_back)
  4.        { Name="Thread_back",IsBackground=true };
  5. th_back.Start();
  6. Console.WriteLine("主线程执行完成!");
  7. }
  8. static void Thread_back()
  9. {
  10. Console.WriteLine("子线程开始执行!");
  11. Thread.Sleep(3000);
  12. Console.WriteLine("子线程执行完成!");
  13. }

运行结果

  从运行结果可以看出,当主线程结束后,进程就终止了,后台线程也被终止,所以没有后台线程结束的输出信息。

 控制线程

  我们使用Thread创建线程后,我们需要对线程进行控制。

  1、  使用Start()方法使线程处于Running状态,线程开始执行。

  2、  使用Join()方法使线程处于WaitSleepJoin状态,在继续执行标准的 COM 和 SendMessage 消息泵处理期间,阻塞调用线程,直到某个线程终止或经过了指定时   间为止。

  3、  使用Sleep()方法,也会使线程处于WaitSleepJoin状态,在经历Sleep()方法定义的时间段后,线程就会被再次唤醒。、

  4、  使用Abort()方法,会使线程处于ResetAbort()状态,线程在接到这个命令的时候,会抛出一个ThradAbordException类型的异常。

各位看官,看代码

  1. using System;
  2. using System.Text;
  3. using System.Threading;
  4. namespace ConsoleThreadContral
  5. {
  6. class Program
  7. {
  8. static void Main(string[] args)
  9. {
  10. Console.WriteLine("mainThread Start!");
  11. Thread th = new Thread(newThread);
  12. th.Start();//将当前实例的状态更改为 ThreadState.Running。
  13. Console.WriteLine("newThread State:{0}",th.ThreadState);
  14. th.Join(100);//在继续执行标准的 COM 和 SendMessage 消息泵处理期间,阻塞调用线程,直到某个线程终止或经过了指定时间为止。
  15. Console.WriteLine("newThread State:{0}", th.ThreadState);
  16. th.Abort();//在调用此方法的线程上引发 ThreadAbortException,以开始终止此线程的过程。 调用此方法通常会终止线程。
  17. Console.WriteLine("newThread State:{0}", th.ThreadState);
  18. }
  19. static void newThread()
  20. {
  21. Console.WriteLine("newThread Start!");
  22. Thread.Sleep(10000);
  23. Console.WriteLine("newThread Complete!");
  24. }
  25. }
  26. }

运行结果

C#基础:使用Thread创建线程的更多相关文章

  1. 第十七节:Runnable创建线程,Thread创建线程,唤醒线程和计数器多线程,线程同步与等待

    Runnable创建线程 public class RunnableDemo implements Runnable{ @Override public void run(){ int i = 1; ...

  2. 使用Thread创建线程

    #_author:来童星#date:2019/12/17#使用Thread创建线程import threadingimport timeclass Sunthread(threading.Thread ...

  3. java基础(26):Thread、线程创建、线程池

    1. 多线程 1.1 多线程介绍 学习多线程之前,我们先要了解几个关于多线程有关的概念. 进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并 ...

  4. 零基础逆向工程33_Win32_07_创建线程

    1 什么是线程(Threads)? 什么是多线程? 怎么在windows中观察多线程? 线程可以简单理解为主程序为解决一个问题而选择的其中一条路线. 同理,多线程就是同时选择不同的路线来解决此问题. ...

  5. Thread 创建线程

    1.该线程变量 无参数 我们可以把线程的变量 理解为一个 委托.可以指向一个方法.有点像c语言中的指向函数的指针. 第1步我们创建了 Thread变量t1 ,第2步创建了一个方法threadChild ...

  6. [非技术参考]C#基础:使用Thread创建线程(1)

    Thread类可以创建和控制线程,Thread类的构造函数重载为接受ThreadStart和ParameterizedThreadStart类型的委托参数.下面我们用一个例子来解释怎样用Thread类 ...

  7. 7种创建线程方式,你知道几种?线程系列Thread(一)

    前言 最近特别忙,博客就此荒芜,博主秉着哪里不熟悉就开始学习哪里的精神一直在分享着,有着扎实的基础才能写出茁壮的代码,有可能实现的逻辑有多种,但是心中必须有要有底哪个更适合,用着更好,否则则说明我们对 ...

  8. C/C++ Muti-Thread多线程编程学习(之)线程Thread | 创建、运行、结束

    文章目录 前言 线程 Thread 创建线程 CreateThread _beginthread _beginthreadex pthread_create 线程运行 结束线程 前言   多线程(Mu ...

  9. JAVA通过继承Thread来创建线程

    创建一个线程的第二种方法是创建一个新的类,该类继承Thread类,然后创建一个该类的实例. 继承类必须重写run()方法,该方法是新线程的入口点.它也必须调用start()方法才能执行. 实例 // ...

随机推荐

  1. Lombok简介

    Lombok简介 和其他语言相比,Java经常因为不必要的冗长被批评.Lombok提供了一系列注解用以在后台生成模板代码,将其从你的类中删除,从而有助于保持你的代码整洁.较少的模板意味着更简洁的代码, ...

  2. WannaCry勒索病毒处理指南

    北京时间2017年5月12日晚,勒索软件"WannaCry"感染事件在全球范围内爆发,被攻击者电脑中的文件被加密,被要求支付赎金以解密文件: 1.开机前断网 如果电脑插了网线,则先 ...

  3. Hibernate表关系映射之一对多映射

    一.基本概述 在表中的一对多,是使用外键关联,通过一张表的一个键另一个表的外键来建立一多关系;而在类中表示为一个类中有一个集合属性包含对方类的很多对象,而在另一个类中,只包含前述类的一个对象,从而实现 ...

  4. Asynchronous programming with async and await (C#)

    Asynchronous Programming with async and await (C#) | Microsoft Docs https://docs.microsoft.com/en-us ...

  5. 解决shell脚本“syntax error near unexpected token `fi'”的问题。

    执行shell脚本的时候,提示如下错误: 查询资料后发现: 执行: vi finddir.sh 然后,输入 :set ff 结果是: 解决方案就是,修改为unix: :set ff=unix 执行保存 ...

  6. java复制图片实现方法

    原图片路径:srcpic 目的图片路径:despic public static void copyPic(String srcpic, String despic){ File file1=new ...

  7. Uninstall Tool3.5.3

    2.卸载所有和MySQL相关的程序,有好几个,注意,一定要删除与MySQL相关的所有的数据,不能用MySQL自带的卸载,我是用Uninstall Tool3.5.3,在卸载程序界面,右键选择与MySQ ...

  8. Codeforces Round #374 (Div. 2) A. One-dimensional Japanese Crossword —— 基础题

    题目链接:http://codeforces.com/contest/721/problem/A A. One-dimensional Japanese Crossword time limit pe ...

  9. jmeter使用笔记——脚本录制,JMeter使用plugins插件进行服务器性能监控

    脚本录制: 1.badboy录制 2.代理服务器录制 ①工作台添加HTTP代理服务器 ②设置目标控制器,分组,排除模式,包含模式(使用正则表达式筛选) ③设置浏览器,手动设置代理服务器,localho ...

  10. 自动化测试框架selenium+java+TestNG——读取csv文件

    读取csv文件可以直接读取,也可以使用javacsv.jar,后者比较简单,这个也可以变相认为是对表格的处理,我们可以在表格中做好数据,存储成csv格式的文件,后续对xlsx表格的操作抽个时间再记录下 ...