C#中,可以使用Thread类来处理(包含创建,启动,挂起,恢复,终止等操作)线程。本文将介绍如何使用Thread类来创建与启动新线程。

Thread类类位于System.Threading命名空间中。

1、线程创建与启动

实例化一个Thread对象,就创建了一个新的线程。

线程创建后调用Start()方法便可以启动新线程。

下面给出一个使用Thread类创建和启动新线程的实例。

文章一开始,给出实例的完整代码,如下:

//完整的示例代码
//求和方法
static void CalcSum()
{
    ;
    ; i < ; i++)
    {
        sum += i;
         ==  && i!=)
        {
            Console.WriteLine("workThread-->i={0}:sum={1}",i,sum);
        }
    }
}

//求差方法
static void CalcGap()
{
    ;
    ; i >= ; i--)
    {
         gap = i-;
          ==  && i != )
         {
             Console.WriteLine("MainThread-->i={0}:gap={1}", i, gap);
         }
    }
}

static void Main(string[] args)
{
    ThreadStart entry = new ThreadStart(CalcSum);//求和方法被定义为工作线程入口
    Thread workThread = new Thread(entry);
    workThread.Start();
    CalcGap();//求差方法被主线程调用
}

在实例中,定义了两个方法,一个求和方法(CalcSum)和一个求差方法(CalcGap)。

求差方法在Main函数中被调用,这个很容易被看出,不做过多解释。

那么实例中的求和方法被谁调用了呢?回答这个问题前,我们需要对Thread类的实例化操作做个简单的说明。

Thread类在实例化时,需要给其构造函数传入一个参数,用于指定线程开始执行的方法(线程入口)。我们查看Thread类的定义,发现其构造函数有以下重载形式:

在这里,我们使用下面这个构造函数来实例化Thread对象(其他构造函数的使用会在后续博文中介绍):

public Thread(ThreadStart start);

该构造函数接受一个ThreadStart 类型的入参。

查看ThreadStart 类型的定义,如下:

public delegate void ThreadStart();

通过阅读定义,我们了解到,ThreadStart是一个委托类型,该委托类型封装的方法没有入参也没有返回值。

ThreadStart委托类型的定义同样位于System.Threading命名空间中。

到这里,我们可以简单总结一下Thread对象的实例化过程,包含以下步骤:

  • 定义一个包含了要执行代码的方法,同时该方法必须具有和ThreadStart委托类型相同的签名(没有入参也没有返回值);
  • 创建ThreadStart委托类型的委托实例;
  • 实例化Thread对象,且将ThreadStart的委托实例作为入参传入Thread类的构造函数。

在本例中的求和方法与 ThreadStart委托类型具有相同的签名,且包含线程需要执行的操作,所以用它来创建ThreadStart委托的委托实例。

再将ThreadStart委托实例作为参数传入Thread构造函数实例化Thread对象。这样就可以告诉编译器线程入口为求和方法CalcSum()。一旦启动线程就会执行这个求和方法指定的操作序列。

实例化Thread对象代码如下:

ThreadStart entry = new ThreadStart(CalcSum);
Thread workThread = new Thread(entry);
static void CalcSum()
{
    //do what you want
}

Thread类型的实例化也可以使用下面的形式来完成:

Thread workThread = new Thread(new ThreadStart(CalcSum));

本例中,传送给Thread类型构造函数的参数是ThreadStart类型的委托。其实,我们也可以采用匿名方法来完成前面Thread类的实例化操作,具体代码如下:

Thread workThread = new Thread(delegate()
{
    ;
    ; i < ; i++)
    {
         sum += i;
          ==  && i != )
         {
              Console.WriteLine("workThread-->i={0}:sum={1}", i, sum);
         }
     }
});

或者:

Thread workThread = new Thread(delegate()
{
     CalcSum();
});

接下来,启动线程,代码如下:

workThread.Start();

代码中的求差方法被Main函数调用,在主线程中被执行。

而求和方法作为工作线程workThread的入口,被工作线程调用。

这里给出两个方法主要是为了说明,此时确实存在两个线程在执行。

至于代码其他细节,这里不做过多解释,有兴趣的可以一探究竟,执行结果如下所示。

就到这里了。

C#多线程网摘 2的更多相关文章

  1. C#多线程网摘 1

    1.每个窗体都有自己的都在不同的线程上运行,如果需要在窗体之间交互,就需要在线程之间交互. 2.当线程Sleep时,系统就退出执行队列一段时间,当睡眠结束时,系统会产生一个时钟中断,从而使线程回到执行 ...

  2. Feedly订阅Blog部落格RSS网摘 - Blog透视镜

    网络信息爆炸的时代,如何更有效率地阅读文章,订阅RSS网摘,可以快速地浏览文章标题,当对某些文章有兴趣时,才点下连结连到原网站,阅读更详细的文章,Feedly Reader阅读器除了提供在线版订阅RS ...

  3. Bloglines订阅Blog部落格RSS网摘 - Blog透视镜

    网络信息蓬勃发展,Blog部落格越来越普及,如果逐一地去浏览网站,势必费时费力,倘若信息可以自己送上门,那就可以节省不少时间,就好像看报纸的标题,有兴趣才点连结,进到网站浏览文章内容,Blogline ...

  4. TCP/IP协议头部结构体(网摘小结)(转)

    源:TCP/IP协议头部结构体(网摘小结) TCP/IP协议头部结构体(转) 网络协议结构体定义 // i386 is little_endian. #ifndef LITTLE_ENDIAN #de ...

  5. Vim命令快捷键(网摘)

    Vim命令快捷键(网摘) 原文出处:[?---->home]

  6. c#与C++类型转换网摘

    转载自 C++和C#转换 https://www.cnblogs.com/zjoch/p/4147182.html c#与C++类型转换,网摘 //c++:HANDLE(void   *)       ...

  7. Delphi 中DataSnap技术网摘

    Delphi2010中DataSnap技术网摘 一.为DataSnap系统服务程序添加描述 这几天一直在研究Delphi 2010的DataSnap,感觉功能真是很强大,现在足有理由证明Delphi7 ...

  8. Python入门及容易!网摘分享给大家!

    Python:Python学习总结 背景 PHP的$和->让人输入的手疼(PHP确实非常简洁和强大,适合WEB编程),Ruby的#.@.@@也好不到哪里(OO人员最该学习的一门语言). Pyth ...

  9. 多线程学习-基础(十三)(学习参考·网摘) ArrayBlockingQueue源代碼解析(base jdk 1.8)

    前记: 这个得首先声明一下,以下大部分内容均参考于:https://blog.csdn.net/wx_vampire/article/details/79585794,本随笔只作为学习作用,侵权删! ...

随机推荐

  1. Div中高度自适应增长方法

    <html> <head> <meta http-equiv="Content-Type" content="text/html; char ...

  2. 使用Github管理项目代码的版本

    作为开源代码库以及版本控制系统,Github拥有140多万开发者用户.随着越来越多的应用程序转移到了云上,Github已经成为了管理软件开发以及发现已有代码的首选方法. 在Git中并不存在主库这样的概 ...

  3. STM32学习笔记(八) SPI总线(操作外部flash)

    1. SPI总线简介 SPI全称串行外设接口,是一种高速,全双工,同步的外设总线:它工作在主从方式,常规需要至少4根线才能够正常工作.SPI作为基本的外设接口,在FLASH,EPPROM和一些数字通讯 ...

  4. Android之打log

    Android之打log 1.在代码中加上自己的log 2,模块编译mm -B或者./mk mm/mmm packages/apps/Contacts/ 3编译成功后install或者push生成的a ...

  5. 第5章 Web自动化测试

    5.1 Selenium简介 5.1.1 自动化测试简介 5.1.2 Selenium简介 5.2 Selenium2环境搭建 5.3 Java基础 5.3.1 新建Java工程和类 5.3.2 Ec ...

  6. spring profile 多环境配置管理

    本地.测试.开发.产品等不同环境文件配置 现象   如果在开发时进行一些数据库测试,希望链接到一个测试的数据库,以避免对开发数据库的影响.   开发时的某些配置比如log4j日志的级别,和生产环境又有 ...

  7. Java完成最简单的WebService创建及使用(REST方式,Jersey框架)

    前言: 一直以来都对WebService感兴趣,但因为难以理解WebService到底是什么,所以了解甚少.周二的时候有个跟我关系比较好的同事想要自己写个WebService的小Demo,希望能够做成 ...

  8. GetProcAddress 宏

    #define FUNC_ADDR(hDll, func) pf##func func = \ (pf##func)GetProcAddress(hDll,#func);\ if(! func) {\ ...

  9. vue服务端渲染

    这篇文章写得还蛮好https://segmentfault.com/a/1190000006701796 从官方网站下载了例子看,用es6写的,还好之前看过es6不然都看不懂,正好es6的东西一起熟悉 ...

  10. 【转载】JSP常用跳转方式

    转自:http://blog.csdn.net/wanghuan203/article/details/8836326 (1)href超链接标记,属于客户端跳转 (2)使用javascript完成,属 ...