C#多线程案例基础

C#多线程案例基础(转)

在学习多线程之前,我们先来看几个概念:

1,什么是进程?
    当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源,当然一个程序也可能开启多个进程
   而一个进程又是由多个线程所组成的。

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

3,什么是多线程?
   多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。
多线程的好处:
   可以提高CPU的利用率。在多线程程序中,一个线程必须等待的时候,CPU可以运行其它的线程而不是等待,这样就大大提高了程序的效率,当然也可以提升用户体验。多线程的      典型应用就是当从数据库中读取大量数据时,会造成界面假死,用户无法操作界面上的其他内容。而使用多线程就可以解决这个问题。
多线程的不利方面:
  线程也是程序,所以线程需要占用内存,线程越多占用内存也越多;
  多线程需要协调和管理,所以需要CPU时间跟踪线程;
  线程之间对共享资源的访问会相互影响,必须解决竞用共享资源的问题;
  线程太多会导致控制太复杂,最终可能造成很多Bug;

注意:任何程序在执行时,至少有一个主线程。

   一个程序从main开始之后,进程启动,为整个程序提供各种资源,而此时将启动一个线程,这个线程就是主线程,它将调度资源,进行具体的操作。Thread开启的线程是主线程下的子线程,是父子关系,此时该程序即为多线程的,这些线程共同进行资源的调度和执行。

Thread类有几个至关重要的方法,描述如下:
   Start():启动线程;
   Sleep(int):静态方法,暂停当前线程指定的毫秒数;
   Abort():通常使用该方法来终止一个线程;
   Suspend():该方法并不终止未完成的线程,它仅仅挂起线程,以后还可恢复;
   Resume():恢复被Suspend()方法挂起的线程的执行;

   用通俗易懂的话来说,多线程可以让计算机"同时"做多件事情,节约时间。多线程可以让一个程序“同时”处理多个事情。

   下面我们通过几个案例来进一步了解多线程

多线程的案例:

案例1:通过多线程执行一个方法

class Program

    {

        static void Main(string[] args)

        {

            MyClass myClass=new MyClass();

Thread thread=new Thread(new ThreadStart(myClass.MyThread1));

            thread.Start();

            Console.WriteLine(thread.ThreadState);

            //注意这里用readline()不能用readkey否则不能出现效果

            Console.ReadLine();

        }

    }

    class MyClass

    {

         public void MyThread1()

         {

             Console.WriteLine("大家好,我是线程1");

         }

    }

      解释下上述代码,首先在MyClass类中定义一个MyThread1方法,该方法无参数无返回值。然后在Main方法中,通过Thread类创建出一个Thread对象thread,但是其构造函数中需要传入一个委托变量,所以通过new ThreadStart(myClass.MyThread1)创建了一个委托变量,接下就可以通过thread.Start()启动线程,这里需要注意的是,调用thread的Start方法后,线程并不是马上执行,而仅仅是被标记为该线程可以执行了,至于线程何时执行,需要听从cpu的调度。

案例2:带参数的线程启动方法

static void Main(string[] args)

        {

            Thread thread=new Thread(new ParameterizedThreadStart(ParameterRun));

            string[] strs = {"李小龙","巩俐","范冰冰"};

            thread.Start(strs);

            Console.ReadLine();

        }

        static void ParameterRun(object obj)

        {

            Console.WriteLine("我是带参数的线程方法");

            string[] arr = obj as string[];

            foreach (string s in arr)

            {

                Console.WriteLine(s);

            }

        }

     这个案例和案例1的唯一区别是创建Thread实例时需要一个带参数的委托变量作为构造函数的参数,而且符合委托规范的方法必须没有返回值,且只能有一个参数,并且参数类型是object的。ParameterRun方法参数赋值时,需要在thread.Start()中进行。

     当然,在真实的项目中,使用不可能这么简单,但是只要了解清楚了带参数线程的使用方式,再复杂的问题都会迎刃而解。

案例3:模拟摇奖机程序

public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();

        }

        private Thread thread;

        //摇奖机是否为启动状态

        private bool isStart = false;

        private void btnok_Click(object sender, EventArgs e)

        {

            if (isStart)

            {

                btnok.Text = "开始";

                isStart = false;

            }

            else

            {

                btnok.Text = "停止";

                isStart = true;

                //单独开启一个线程摇号,避免主线程假死

                thread = new Thread(Show);

                thread.Start();

            }

        }

        public void Show()

        {

            Random random=new Random();

            while (isStart)

            {

                lbl1.Text = random.Next(0, 10).ToString();

                lbl2.Text = random.Next(0, 10).ToString();

                lbl3.Text = random.Next(0, 10).ToString();

                //让当前线程睡一会儿

                Thread.Sleep(100);

            }

        }

        private void Form1_Load(object sender, EventArgs e)

        {

            //不检查控件的跨线程操作

            Control.CheckForIllegalCrossThreadCalls = false;

        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)

        {

            //在窗体关闭(主线程)前关闭子线程

            if (thread!=null)

            {

                thread.Abort();

            }

        }

    }

写该程序时,需注意几点:

1,         在窗体的Load事件中设置不检查控件的跨线程操作

2,         在主窗体关闭前,结束子线程的执行

3,         为了避免随机数生活速度过快,使用Thread.Sleep(),让生成随机数的线程休息一段时间

当然,我们讲解的只是多线程的使用方式,如果想要对多线程的底层实现有更深入的了解,还需查询更多书籍和资料。希望这篇文章能对您有所帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/460768.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么是shell?

本文源于网络资源的学习与整理,如有侵权请告知删除。 shell的概念 shell,它的意思是“壳”,如果理解shell在linux中的作用(内核的外壳,既保护了内核,也向用户提供了操作内核的接口)&#xff0c…

chmod的理解

ll file 共有是十位第一位:如果是 - 表示它是文件第一位:如果是d 表示它是目录剩下的333 分别表示 属主u属组g其他用户o所以如下:转载于:https://blog.51cto.com/zlong37/1567472

中国象棋程序的设计与实现(五)--回答CSDN读者的一些问题

最近写了很多文章,同时,也上传了很多免积分的FansUnion原创的优质资源,有兴趣的同学可以看来我的CSDN博客瞧瞧 http://blog.csdn.net/FansUnion。近期,收到了不少读者的评论、反馈、留言。对于其中的一些问题,我想专门…

几种常见的shell:sh、bash、csh、tcsh、ash

以下内容源于C语言中文网的学习与整理,非原创,如有侵权请告知删除。 我们知道,Windows、Mac OS、Android 等操作系统由一家公司开发,所有的核心软件和基础库都由一家公司做决定,容易形成统一的标准,一般不会…

第九周项目6-穷举法之年龄几何

张三、李四、王五、刘六的年龄成一等差数列,他们四人的年龄相加是26,相乘是880,求以他们的年龄为前4项的等差数列的前20项。 构建代码: /**Copyright (c) 2014,烟台大学计算机学院*All gight reserved.*文件名称:temp.…

JavaScript操作大全整理(思维导图七--字符串函数)

7. JavaScript 字符串函数 转载于:https://www.cnblogs.com/yuxia/p/3360824.html

进入shell的两种方法

以下内容源于C语言中文网的学习与整理,非原创,如有侵权请告知删除。 方法一:在图形界面中打开终端 在图形界面下,进入 Shell 的方法是使用 Linux 桌面环境中的终端模拟包,也就是我们常说的终端,这样在图形桌…

外籍主管眼中的阿里巴巴

尝试接受一份新领域的职位有时是值得的,而对雇主来说,任命“非正统人选”从而给团队带来清新气息,也是有好处的。 这是詹姆斯•哈迪(James Hardy)的经验。一位知道他想转行的朋友和他联系,后来他就得到了现在的职位——在线零售商…

Shell脚本运行方法

以下内容源于C语言中文网的学习与整理,非原创,如有侵权请告知删除。 在文本编辑器中编写如下代码并保存为test.sh。 #!/bin/bash echo "Hello World !" 这个文件的扩展名为sh(sh代表shell),但其实扩展名并不…

Perl 中级教程 第5章课后习题

5. 9. 1. 练习1 [5 分钟] 先不要运行程序, 看看你能否判断出这程序的哪部份出了问题?如果你看不出 来, 就可以运行一相程序, 得到些暗示, 来看是否能修改好: my %passenger_1 { name > Ginger, age > 22, occupation > Movie Star, real_age &…

SQL Server 固定角色

1、 查看固定服务器角色 execute sp_helpsrvrole; 管理: execute master..sp_addsrvrolemember logingNameneeky rolenamesysadmin; go execute master..sp_dropsrvrolemember logingNameneeky rolenamesysadmin; go 2、 查看固定数据库角色成员 execute sp_helprol…

Shell变量与Shell特殊变量

以下内容源于C语言中文网的学习与整理,非原创,如有侵权请告知删除。 一、Shell变量 脚本语言在定义变量时通常不需要指明类型,直接赋值就可以,Shell 变量也遵循这个规则。在 Bash shell 中,每一个变量的值都是字符串&…

如何在我们项目中利用开源的图表(js chart)

最近觉得应该把自己在技术上的一些心得记录在博客里面跟大家分享,一起讨论,一起成长! 这篇随笔主要为介绍chart在项目中的运用,因为在我们看到一些开源的chart时候,是使用纯js 或者建立在一些插件(例如:jqu…

vb.net中东软医保接口的调用

前段时间接了个医院管理系统的小项目,要求接入本市医保接口,本市的医保接口采用的是东软的接口平台,为动态库版,只提供了几个配置文件和几个DLL动态库,文档中写的不够详细,并没有各种语言平台的例子&#x…

Shell替换:转义字符、变量替换,命令替换

以下内容源于C语言中文网的学习与整理,非原创,如有侵权请告知删除。 一、转义字符 如果表达式中包含特殊字符,Shell 将会进行替换。除了在双引号中使用变量会进行替换,转义字符也是一种替换。 举个例子: #!/bin/basha1…

关于过去的这一个月——面试经历

终于到了周末,感觉很久很久没有去闲下来了!9月过半,我还在Symantec做实习生,做点单位的工作,研究点自己喜欢的事情,小日子过得还是蛮舒服的。中秋节提前买好了去女朋友家的动车票,规划着去这里那…

python读取postgresql数据库并发送相关提醒邮件

代码如下:#!/usr/bin/env pythonimport smtplibfrom email.mime.text import MIMETextimport psycopg2import datetimefrom time import *mail_host "smtp.XXX.com" mail_user "XXX" mail_pass "XXX" mail_postfix&…

Shell运算符:算术运算符、关系运算符、布尔运算符等

以下内容源于C语言中文网的学习与整理,非原创,如有侵权请告知删除。 expr表达式计算工具 原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,其中 expr 最常用。 expr 是一款表达式计算工具&…

AjaxControlToolkit的使用

摘自&#xff1a;http://www.cnblogs.com/zm235/archive/2008/05/09/1189558.html 暂时的做法&#xff1a; 把AjaxControlToolkit.dll复制到项目的bin目录里面,然后配置Web.config文件&#xff0c;例如&#xff1a; <configuration><system.web><pages><c…

Shell的注释

关于注释&#xff0c;了解三点内容。 &#xff08;1&#xff09;Shell脚本中&#xff0c;以“#”开头的行就是注释&#xff0c;会被解释器忽略。 &#xff08;2&#xff09;sh里没有多行注释&#xff0c;只能每一行加一个#号。 &#xff08;3&#xff09;遇到大段的代码需要…