C#thread线程类

首先需要先说明下线程是什么,一台计算机核心是CPU,CPU中可以运行应用程序,这里我们把应用程序理解成进程,而一个进程是由至少一个或多个线程组成的。这里要说明的是进程和线程的关系,进程是包含多个线程的,各个线程就可以单独运行,提高效率。比如我们在一个程序里面要执行一个功能,由于程序执行是由上而下顺序的,那么如果我们在前面有一个特别耗时的方法,比如读取或者下载一个大文件,那么整个程序的运行就会特别缓慢,如果这时我们把这个特别耗时的方法放在线程中去执行,那么这个线程是单独运行,可以理解为与下面的程序同时运行,这样就可以大大提高程序的执行效率。
举个例子:一个CPU相当于一个公司,这个公司是在一直运行的,这个公司里面有各个部门,比如销售部门,技术部门,采购部门,生产部门等,可以把这些部门理解成进程,而这些部门的运行需要人来进行操作,那么我们把这里面的人的行为看成是线程,有的部门事情比较多,进程比较大,所以需要线程就比较多。这些线程是可以几乎同时运行,每一个线程可以调用该进程内的空间。
首先我们先定义了两个用于操作的类,这就是线程所要执行的:
下面是第一个类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace 线程的使用
{
    class thr
    {
        private string name;
        private string path;
        public thr(string NAM, string PAT)
        {
            name = NAM;
            path = PAT;

        }
        public void readload()
        {
            Console.WriteLine("开始读取第一个文件:文件名:{0},第一个文件路径:{1}",name,path);
            Thread.Sleep(5000);
            //线程休息5秒钟;
            Console.WriteLine("读取第一份文件完成");
        }
    }
}

下面是第二个类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace 线程的使用
{
    class thr1
    {
        private string name1;
        private string path1;
        public thr1(string NAM, string PAT)
        {
            name1 = NAM;
            path1 = PAT;

        }
        public void readload1()
        {
            Console.WriteLine("开始读取第二份文件:第二份文件名:{0},第二份文件路径:{1}", name1, path1);
            Thread.Sleep(2000);
            //线程休息2秒钟;
            Console.WriteLine("读取第二份文件完成");
        }
    }
}

这两个类中的方法所完全执行的时间有长短,第一个时间长一点,第二个时间短一点,来看主程序:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace 线程的使用
{
    class Program
    {
        static void Main(string[] args)
        {
            thr threa = new thr("这是第一个文件名字","这里一个个文件路径");
            //创建一个类的对象;输入该对象的输入参数;
            Thread the = new Thread(threa.readload);
            //实例一个线程,在线程中,填上需要加载的方法;
            thr1 threa1 = new thr1("这是第二份文件名字", "这里第二份路径");
            //创建一个类的对象;输入该对象的输入参数;
            Thread the1 = new Thread(threa1.readload1);
            //实例一个线程,在线程中,填上需要加载的方法;
            the.Start();
            //开启第一个文件的线程;
            the1.Start();
            //开启第二个文件的线程;
            Console.WriteLine("这是直接显示的");
            Console.Read();
        }
      
    }
}

这里如果是按照由上而下的执行顺序,那么应该是先结束第一个文件的,再结束第二个文件的,最后显示最后一段话,然而加了线程之后就使得这些线程独立执行,可以理解为同时运行,这里的main函数里面除了两个线程外就是一个“这是直接显示的”,当显示这句话之后,main函数就停在了read上面,而此时开启的线程则是自己继续独立运行,我们来看下运行的结果显示:
在这里插入图片描述
可以看到最先执行的反而是最后一条语句,两个线程中,尽管是先开启的第一个线程,后开启的第二个线程,但由于第一个线程的执行时间较长,所以第二个线程是先完成的。就可以理解为这些线程是独立几乎同时再工作的。
那么问题就来了,如果我一个main程序已经运行结束,那么在这个main函数里的未完成的线程是不是会继续运行,就比如我想直接关了一个应用程序,但是这个应用程序还在进行一定的操作,就比如我用手机玩游戏,突然上课了,我想直接关闭这个应用程序,尽管可能我正在打怪升级,但是我希望它可以强制退出怎么办呢。
要解决这个问题,我们需要明白,线程是分为前台线程和后台线程的,当main函数运行完之后,如果其中的前台线程还没完成,则会继续运行前台线程,只要前台线程在运作这个应用进程就会继续运行,就比如打游戏可能结束了一个任务之后,我还可以进行其他的一些操作等,如果是后台线程,当main结束后,不管该线程有没有完成都会强制结束,由于我们这里是thread定义的线程,所以会默认是前台程序;例如程序:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace 线程的使用
{
    class Program
    {
        static void Main(string[] args)
        {
            thr threa = new thr("这是第一个文件名字","这里一个个文件路径");
            //创建一个类的对象;输入该对象的输入参数;
            Thread the = new Thread(threa.readload);
            //实例一个线程,在线程中,填上需要加载的方法;
            thr1 threa1 = new thr1("这是第二份文件名字", "这里第二份路径");
            //创建一个类的对象;输入该对象的输入参数;
            Thread the1 = new Thread(threa1.readload1);
            //实例一个线程,在线程中,填上需要加载的方法;
            the.Start();
            //开启第一个文件的线程;
            the1.Start();
            //开启第二个文件的线程;
            Console.WriteLine("这是直接显示的");
            //Console.Read();
            //这里是把read()去了,就是main函数直接结束了;
        }
      
    }
}

结果是没有什么变化的,因为这个是默认前台线程:
在这里插入图片描述
如果我们把第一个时间较长的线程设置为后台线程内,这需要用到isbackground来对其进行设置:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace 线程的使用
{
    class Program
    {
        static void Main(string[] args)
        {
            thr threa = new thr("这是第一个文件名字","这里一个个文件路径");
            //创建一个类的对象;输入该对象的输入参数;
            Thread the = new Thread(threa.readload);
            //实例一个线程,在线程中,填上需要加载的方法;
            thr1 threa1 = new thr1("这是第二份文件名字", "这里第二份路径");
            //创建一个类的对象;输入该对象的输入参数;
            Thread the1 = new Thread(threa1.readload1);
            //实例一个线程,在线程中,填上需要加载的方法;
            the.Start();
            //开启第一个文件的线程;
            the.IsBackground = true;
            //设置第一个是后台线程;
            the1.Start();
            //开启第二个文件的线程;
            Console.WriteLine("这是直接显示的");
            //Console.Read();
            //这里是把read()去了,就是main函数直接结束了;
        }
      
    }
}

在这里插入图片描述
可以发现第一个文件没有显示完成,这是因为main函数结束了就强制关闭,这就是前台此案从和后台线程,同时也可以设置线程的优先级等,就是先处理哪一个后处理哪一个。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值