C#线程

线程


  线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数。

  多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。

  多线程可以提高CPU的利用率。在多线程程序中,一个线程必须等待的时候,CPU可以运行其它的线程而不是等待,这样就大大提高了程序的效率。

  在 C# 中,System.Threading.Thread 类用于线程的工作。线程生命周期开始于System.Threading.Thread 类的对象被创建时,结束于线程被终止或完成执行时。

  我们在编写线程程序时首先要引入System.Threading空间。

创建线程


  当 C# 程序开始执行时,主线程自动创建。使用 Thread 类创建的线程被主线程的子线程调用。通过Start()方法来启动线程。如下面例子:

using System;
using System.Threading;
namespace test
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Main start");
            /*=========================================/
            Thread 类拥用4个重载的构造函数,常用的一个接收一个ThreadStart类型的参数
            public Thread ( ThreadStart start)
            ThreadStart是一个委托,定义如下
            public delegate void ThreadStart()
            /=========================================*/
            Thread th = new Thread(new ThreadStart(ThreadMethod));
            //也可简写为new Thread(ThreadMethod);
            th.Start(); //启动线程
            for (char i = 'a'; i < 'k'; i++)
            {
                Console.WriteLine("Main Thread: {0}", i);
                Thread.Sleep(100);
            }
            th.Join(); //主线程等待辅助线程结束
            Console.WriteLine("Main Thread end.");
        }
        static void ThreadMethod()
        {
            Console.WriteLine("Second Thread start...");
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("Second Thread:{0}", i);
                Thread.Sleep(200);
            }
            Console.WriteLine("Second Thread end.");
        }
    }
}

后台线程


  在默认情况下,用Thread类创建的线程是前台线程。在用thread类创建线程时,可以设置IsBackground属性,以确定该线程是前台线程还是后台线程。将线程的IsBackgrond属性设置为false(默认值) 。

  程序运行结果为:

  当我们将IsBackground属性值改为true时,有时可以看到与上面相同的运行结果——新线程的启动消息,但没有结束消息。去试一试吧,后台线程特别适合于完成后台任务,如关闭word等。

控制线程


  C#的Thread类为我们提供了几个重要的方法来控制线程:

  Start():启动线程;

  Sleep(int):静态方法,暂停当前线程指定的毫秒数;

  Abort():通常使用该方法来终止一个线程;

  Suspend():该方法并不终止未完成的线程,它仅仅挂起线程,以后还可恢复;

  Resume():恢复被Suspend()方法挂起的线程的执行。

  例如在前面中我们已经使用了Sleep函数。

线程的优先级


  当线程之间争夺CPU时间时,CPU 是按照线程的优先级给予服务的。在C#应用程序中,用户可以设定5个不同的优先级,由高到低分别是Highest,AboveNormal,Normal,BelowNormal,Lowest,在创建线程时如果不指定优先级,那么系统默认为ThreadPriority.Normal。

  给一个线程指定优先级,我们可以使用如下代码:

Thread myThread = new Thread(ThreadMethod); //声明线程
myThread.Priority=ThreadPriority.Lowest; //设定优先级为最低

lock


  当我们使用线程的时候,效率最高的方式当然是异步,即各个线程同时运行,其间不相互依赖和等待。但当不同的线程都需要访问某个资源的时候,就需要同步机制了,也就是说当对同一个资源进行读写的时候,我们要使该资源在同一时刻只能被一个线程操作,以确保每个操作都是有效即时的,也即保证其操作的原子性。lock是C#中最常用的同步方式,格式为:lock(objectA){codeB} 。

using System;
using System.Threading;
namespace test
{
    class Program
    {
        static void Main(string[] args)
        {
            threda t = new threda();
            threda.obj.i = 10;
            Thread th1 = new Thread(new ThreadStart(t.hhh));
            th1.Name = "th1";
            th1.Start();

            Thread th2 = new Thread(new ThreadStart(t.hhh));
            th2.Name = "th2";
            th2.Start();
            Console.ReadKey();
        }
    }
    class threda
    {
        public static sss obj = new sss();

        public void hhh()
        {
            lock (obj) //lock锁
            {
                for (int i = 0; i < 7; i++)
                {
                    Thread.Sleep(500);

                    if (obj.i > 0)
                    {
                        obj.i--;
                        Console.WriteLine("Current Thread Name: " + Thread.CurrentThread.Name + ", obj.i= " + obj.i);
                    }
                }
            }
        }
    }

    class sss
    {
        public int i;
    }
}

  通过设定线程的优先级,我们可以安排一些相对重要的线程优先执行,例如对用户的响应等等。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Kurt Niu 的博客

C# Int 类型线程不安全

之前统计报表算法做了一个优化,一个查询二十分钟导致客户端超时,优化到只需要5秒钟。后来发现for循环里数据合并的时候耗时,就用并行做优化。但是发现并行后丢居然数...

1092
来自专栏搞前端的李蚊子

如何在vue中使用sass

使用sass,我们需要安装sass的依赖包 npm install --save-dev sass-loader //sass-loader依赖于node-sa...

4118
来自专栏抠抠空间

Django之views系统

Django的View(视图)简介 一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应。 响应可以是一张网页...

4227
来自专栏Jackson0714

干货分享:详解线程的开始和创建

2876
来自专栏韩东吉的Unity杂货铺

零基础入门 42:更新Unity2017快捷键清除日志

Hello,之前在零基础入门系列里,有发过关于快捷键清除日志的文章,但是当时的Unity版本是Unity5.5,很多人和我说用起来都还蛮方便,但是随着2017的...

3602
来自专栏每日一篇技术文章

微信小程序_09 HTTPS

标准模板 var util = require('../../utils/util.js') wx.request({ url: 'https://URL...

3041
来自专栏JetpropelledSnake

Django学习笔记之Django视图View

1623
来自专栏领域驱动设计DDD实战进阶

微服务实战(六):落地微服务架构到直销系统(事件存储)

在CQRS架构中,一个比较重要的内容就是当命令处理器从命令队列中接收到相关的命令数据后,通过调用领域对象逻辑,然后将当前事件的对象数据持久化到事件存储中。主要的...

1352
来自专栏博客园

Asp.Net Web API(二)

当然,你也可以创建一个Web API项目,利用 Web API模板,Web API模板使用 ASP.Net MVC提供API的帮助页。

1721
来自专栏大内老A

通过重建Hosting系统理解HTTP请求在ASP.NET Core管道中的处理流程[中]:管道如何处理请求

从上面的内容我们知道ASP.NET Core请求处理管道由一个服务器和一组中间件构成,所以从总体设计来讲是非常简单的。但是就具体的实现来说,由于其中涉及很多对象...

3089

扫码关注云+社区

领取腾讯云代金券