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

static void Main(string[] args)
{
    //region只是用来包裹代码用的,实际没有什么用
    #region Thread无参数举例
    Thread th = new Thread(ThreadChild);
    th.Start();
    Console.WriteLine("Main Thread Start!");
    #endregion
 
    Console.ReadKey();
}
static void ThreadChild()
{
    Console.WriteLine("Child Thread Start!");
}

输出结果:

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


给线程传递数据

上面的例子演示了怎样用Thread类来创建一个不带传参的线程,下面我门来创建一个带传入参数的线程。

给线程传递参数,有两种方式:一种是使用带ParameterizedThreadStart委托参数的Thread的构造函数,另外一种是定义一个自定义类。

首先我们使用ParameterizedThreadStart委托来创建有传入参数的类。使用ParameterizedThreadStart,线程的入口(线程调用的方法)必须有一个Object类型的参数,使用Object我们首先想到的就是类型不安全。而且在执行线程的时候多半有装箱拆箱操作。管它的,我们先用这种方式来创建一个带传入参数的线程!!

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

static void Main(string[] args)
{
    #region 使用parameterizedThreadStart委托执行带参数的委托
    Thread th2 = new Thread(Thread_param);
    th2.Start(20);
    #endregion
 
    Console.WriteLine("Main Thread");
    Console.ReadKey();
}
 
static void Thread_param(object msg)
{
    int message = (int)msg;
    Console.WriteLine("Result:{0}", message);
}

运行结果:


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

class Program
{
    static void Main(string[] args)
    {
        #region 使用自定义类实现带参数的线程
        MyThead<string> myThread = new MyThead<string>("Child_Thread");
        Thread th3 = new Thread(myThread.ThreadChild);
        th3.Start();
        #endregion
 
        Console.WriteLine("Main Thread is going!");
        Console.ReadKey();
    }
 
}//class 
 
class MyThead<T>
{
    private T data;
 
    public MyThead(T data)
    {
        this.data = data;
    }
 
    public void ThreadChild()
    {
        Console.WriteLine("Child Thread Started! Result:{0}", data);
    }
}

运行结果:


后台线程

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

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

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

static void Main(string[] args)
{
    Thread th_pre = new Thread(Thread_pre) {Name="Thread_pre", IsBackground=false};
    th_pre.Start();
    Console.WriteLine("主线程执行完成");
}
 
static void Thread_pre()
{
    Console.WriteLine("子线程开始执行");
    Thread.Sleep(3000);
    Console.WriteLine("子线程完成执行");
}

执行结果:

下面我们来看看后台线程:

static void Main(string[] args)
{
    Thread th_pre = new Thread(Thread_pre) {Name="Thread_pre", IsBackground=true};
    th_pre.Start();
    Console.WriteLine("主线程执行完成");
}
 
static void Thread_pre()
{
    Console.WriteLine("子线程开始执行");
    Thread.Sleep(3000);
    Console.WriteLine("子线程完成执行");
}

运行结果:

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


提示:

上面的代码部分有一个C#3.0的新特性,对象初始化设置。

例如,有如下类:

public class Document
{
    public string Title { get; set; }
    public string Content { get; set; }
}

C# 2.0 为 Document 对象的属性赋值,可能通过如下的方式:

Document doc = new Document();
doc.Title = "标题";
doc.Content = "内容";

用了三行代码,能不能更简洁一点呢?可以用构造函数,这的确是个办法,但也不是特别好,因为不是每种情况下构造函数都会把所有的属性列出来。C# 3.0 的对象初始化设置提供了一种方案:

Document doc = new Document { Title = "标题", Content = "内容" };

  • 去掉实例化时的小括号,如果需要构造函数初始化其他成员变量,这里要加上小括号;
  • 增加大括号;
  • 在大括号里为需要赋值的属性赋值。

其实这段代码是这样工作的:

  • 首先,用没有参数的构造函数去实例化对象,如果要初始化其他的成员变量,就不会调用无参的构造函数;
  • 然后,根据大括号中的属性及属性值,为对象属性赋值。

这一节很简单,就是了解一下线程的创建和给线程传递参数的方法,同时说了一个前台线程和后台线程,加入了一个C#3.0的新特性。其他的没有什么。

原文转载地址:http://www.cnblogs.com/lvcy/archive/2012/06/16/2551539.html

转载于:https://www.cnblogs.com/stemon/p/4197314.html

[非技术参考]C#基础:使用Thread创建线程(1)相关推荐

  1. 主线程是如何向子线程传递数据的?_c++ 利用thread创建线程

    用进行多线程开发 小时候,老师总是教育我们上课要专心,"一心不可二用".可是CPU这个不听话的"熊孩子"偏偏却在一个芯片中加入了两个甚至多个运算核心,想要一&q ...

  2. Thread创建线程

    创建线程 1.继承Thread类创建线程 public class MyThread extends Thread{public void run(){System.out.println(" ...

  3. python线程创建对象_Python多线程编程基础:如何创建线程?

    Python标准库threading中的Thread类用来创建和管理线程对象,支持使用两种方法来创建线程: 1)直接使用Thread类实例化一个线程对象并传递一个可调用对象作为参数: 2)继承Thre ...

  4. 使用Runnable配合Thread创建线程

  5. 如何创建线程?如何创建扩展Thread类?

    大多数情况,通过实例化一个Thread对象来创建一个线程.Java定义了两种方式: · 实现Runnable 接口. · 可以继承Thread类. 前一篇文章介绍了下面介绍了实现Runnable 接口 ...

  6. Thread类创建线程

    目录 1.在java中执行多线程编辑 1.1通过Thread类创建线程 1.2创建线程方法2 1.3创建线程方法3 1.4创建线程方法4 1.5创建线程方法5 2.多线程执行效率 2.1两个变量同时自 ...

  7. Java多线程学习六:使用线程池比手动创建线程好在那里以及常用线程池参数的意义

    为什么要使用线程池 首先,回顾线程池的相关知识,在 Java 诞生之初是没有线程池的概念的,而是先有线程,随着线程数的不断增加,人们发现需要一个专门的类来管理它们,于是才诞生了线程池.没有线程池的时候 ...

  8. java多线程-线程创建-线程池-java内存模型

    文章目录 ==多线程基础== 进程 线程 浏览器的进程和线程(案例) 线程的异步和同步 多线程的优势 ==多线程的实现方式== 第一种:继承Thread类 第二种:实现Runnable接口 第三种:通 ...

  9. java中创建线程的四种方式及线程池详解

    众所周知,我们在创建线程时有四种方法可以用,分别是: 1.继承Thread类创建线程 2.实现Runnable接口创建线程 3.使用Callable和Future创建线程 4.使用线程池创建(使用ja ...

最新文章

  1. 报错解决:ResourceExhaustedError: OOM when allocating tensor with shape
  2. Caffe中的损失函数解析
  3. 【转】ASP中的SQL注入
  4. python跨目录调用_python 跨目录访问文件
  5. C++|Qt工作笔记-C++获取当前系统时间,Qt获取当前系统时间及各标准间转化
  6. 力扣98. 验证二叉搜索树(JavaScript)
  7. HOW TO: Troubleshoot development errors in MOSS 2007
  8. Vue解决无数据图片闪现的问题
  9. 腾讯微博开放平台开发者服务协议 2.1、3.6 解读
  10. linux4.12 交叉编译链,交叉编译工具链(很详细)
  11. pubwinol免刷_Pubwin万象OL实名一键自动处理程序
  12. python全栈测试开发_用于全栈自动化测试的最佳Python工具
  13. 计算机毕设(附源码)JAVA-SSM基于Web美食网站设计
  14. win10无法完成更新正在撤销更改怎么办?windows10无法更新正在撤销更改的解决方法
  15. 【BZOJ4327】[JSOI2012] 玄武密码(AC自动机的小应用)
  16. 拉格朗日对偶问题的一些介绍
  17. 【论文笔记】基于分层深度强化学习的移动机器人导航方法
  18. 深入浅出Java23种设计模式(一)
  19. 2022年全国最新中级消防设施操作员模拟题库及答案
  20. Arduino-ESP8266检测温湿度上传阿里云

热门文章

  1. Javascript在IE中的有趣错误
  2. Juniper SRX 常用命令
  3. 2017年2月20日 Adaboost
  4. Open-E DSS V7 应用系列之六 构建软件iSCSI
  5. 学习使用Markdown最基础的语法(编辑器通用)
  6. 利用Graphviz 画结构图
  7. UML类图关系大全 and 报表的基本用法
  8. 【初识】-JUC·Executor框架
  9. Oracle备份恢复一(手动备份)
  10. 具体解释Hibernate中的事务