【.NET线程--进阶(一)】--线程方法详解
上篇博客从线程的基本概况开始着重讨论了线程,进程,程序之间的区别,然后讨论了线程操作的几个类,并通过实例来说明了线程的创建方法。本篇博客将会带大家更深入的了解线程,介绍线程的基本方法,并通过一个Demo使用委托来调用线程之外的对象。
前篇博客基础:【GDI+编程--番外篇(二)】--从事件看委托
【.NET线程--开篇】--线程从零开始
线程
多线程优缺点
多线程的使用会帮助程序提高响应速度,因为可以同时执行多个任务这样对比一个个的来完成任务来说提高了响应的速度,较之添加多CPU来说多线程提高了强大的技术来执行多个任务。虽然多线程提高了响应速度,但同时牺牲了资源,由于多线程的执行它会占用多个资源,为了避免资源访问的冲突,往往会在每个线程中都会创建自己的资源,这样导致了资源的浪费。另外如果线程过多,则其中大多数线程都不会产生明显的进度,如果大多数当前线程处于一个进程中,则其他进程中的线程的调度频率就会很低。
线程基本方法
下表包括了在线程编程过程中常用的基本方法。
可用于控制单个线程的方法
方法 | 操作 |
---|---|
Start | 使线程开始运行。 |
Sleep | 使线程暂停指定的一段时间。 |
Suspend | 在线程到达安全点时,使其暂停。 |
Abort | 在线程到达安全点时,使其停止。 |
Resume | 重新启动挂起的线程 |
Join | 使当前线程一直等到另一线程完成。 在与超时值一起使用时,如果该线程在分配的时间内完成,此方法将返回 True。 |
Note: 安全点是指代码中公共语言运行时可以安全地执行自动“垃圾回收”的位置。垃圾回收是指释放不再使用的变量并回收内存的过程。 调用线程的 Abort 或 Suspend 方法时,公共语言运行时将对代码进行分析,确定让线程停止运行的适当位置。
Demo1:线程,方法--委托
自己做的一个小Demo来实现多线程,当点击开始按钮后会在文本框中填写数字,与此同时加载进度条,读取进度,点击暂停后线程会停止。另外可以在文本框中输入暂停时间来指定线程暂停时间,在暂停后继续执行。
Demo下载地址:线程常用方法示例
在点击开始按钮后会同时创建两个线程,分别为showNumThread和pBarThread,用来向文本框中写入数字和加载进度条。这里需要说明的是,一般情况下线程内部是不允许调用线程外创建的对象的,创建的两个线程都调用了线程外部的对象,是怎么实现的呢?使用的是委托来异步执行程序来实现了调用线程外部的方法。
- /// <summary>
- /// 开始按钮事件,创建线程并为线程指定方法
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void btnStart_Click(object sender, EventArgs e)
- {
- pBarThread = new Thread(new ThreadStart(this.ExepBarShow)); //创建进度条线程
- showNumThread = new Thread(new ThreadStart(this.ExeShowNum)); //创建显示文本框中的文字线程
- //开始两个已创建的线程
- this.StartThread(showNumThread);
- this.StartThread(pBarThread);
- }
- /// <summary>
- /// 使用委托执行ShowNumToText方法
- /// </summary>
- private void ExeShowNum()
- {
- try
- {
- MethodInvoker mInvoker = new MethodInvoker(this.ShowNumToText); //声明托管委托,并为委托执行执行的方法
- //执行委托方法,向Text中写入文字
- while (true)
- {
- this.BeginInvoke((Delegate)mInvoker); //异步执行执行的委托
- Thread.Sleep(1000); //线程停顿1秒后继续执行
- }
- }
- catch { }
- }
- /// <summary>
- /// 先文本框txtNum中写入文字
- /// </summary>
- private void ShowNumToText()
- {
- i = i + 1; //i累加
- txtNum.Text = txtNum.Text + " " + (i + 1).ToString(); //向txtNum中写入文字
- }
- /// <summary>
- /// 执行pBarShow方法,加载进度条,让进度条读取进度
- /// </summary>
- private void ExepBarShow()
- {
- try
- {
- MethodInvoker mInvoker = new MethodInvoker(this.pBarShow); //声明并创建委托,为委托执行进度
- //异步执行委托
- while (true)
- {
- this.BeginInvoke((Delegate)mInvoker);
- Thread.Sleep(10);
- }
- }
- catch { }
- }
- /// <summary>
- /// 执行进度条读取进度
- /// </summary>
- private void pBarShow()
- {
- this.pgBar.PerformStep();
- }
- /// <summary>
- /// 线程开始方法
- /// </summary>
- /// <param name="th">Thread对象,需要开始的线程</param>
- private void StartThread(Thread th) {
- th.Start();
- }
- /// <summary>
- /// 线程结束方法
- /// </summary>
- /// <param name="th">Thread对象,需要结束的线程</param>
- private void EndThread(Thread th) {
- th.Interrupt(); //中断线程
- th.Abort(); //终止线程
- th = null;
- }
- /// <summary>
- /// 停止线程事件
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void btnStop_Click(object sender, EventArgs e)
- {
- try
- {
- this.TestThead(); //验证线程是否存在,如果没有存在将会抛错
- this.EndThread(this.pBarThread); //结束线程
- this.EndThread(this.showNumThread); //结束线程
- }
- catch (Exception ex)
- {
- //提示错误信息
- MessageBox.Show(ex.Message , "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
- }
- }
- /// <summary>
- /// 终止线程事件
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void btnEnd_Click(object sender, EventArgs e)
- {
- try
- {
- this.TestThead(); //验证线程是否创建
- this.EndThread(this.pBarThread);//结束线程
- this.EndThread(this.showNumThread); //结束线程
- txtNum.Text = ""; //清空文本框内容
- i = 0; //数字充值
- this.pgBar.Value = 0;//进度条重置
- }
- catch (Exception ex)
- {
- //显示错误信息
- MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
- }
- }
- /// <summary>
- /// 执行指定线程停顿时间
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void btnStopMinute_Click(object sender, EventArgs e)
- {
- try
- {
- int j = int.Parse(textBox1.Text); //获取终止的时间
- Thread.Sleep(j); //将线程暂停指定的时间
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
- }
- }
- /// <summary>
- /// 验证线程是否存在方法
- /// </summary>
- private void TestThead() {
- if (pBarThread ==null)
- {
- throw new Exception ("未创建线程,请创建线程后操作!");
- }
- if (showNumThread == null)
- {
- throw new Exception ("未创建线程,请创建线程后操作!");
- }
- }
Demo2:Join方法使用实例
Join方法能在指定的线程中插入一个线程,当插入的线程执行完成后才会继续执行被插入的线程。.NET为我们重载了此方法,能够为方法传递参数来指定经过的时间,此时该方法的作用与Sleep相类似,执行经过多长时间后来执行被插入的线程。Join方法的灵活运行能够实现线程之间的执行顺序。
- using System;
- using System.Threading;
- namespace TestJoin
- {
- /// <summary>
- /// Join方法验证实例,线程t1使用了join方法,线程t2没有使用join方法
- /// </summary>
- class Program
- {
- static void Main(string[] args)
- {
- //创建新线程,为线程执行行为
- Thread t1 = new Thread(() =>
- {
- Thread.Sleep(1000);
- Console.WriteLine("t1 is ending.");
- });
- t1.Start(); //开始线程
- t1.Join(); //在主线程中插入t1线程,先执行t1,线程后执行主线程
- Console.WriteLine("t1.Join() returned."); //执行主线程,提示t1已经完成
- //创建新线程,为线程执行行为
- Thread t2 = new Thread(() =>
- {
- Thread.Sleep(1000);
- Console.WriteLine("t2 is ending.");
- });
- t2.Start(); //开始线程
- Console.WriteLine("t2.Join() returned."); //执行主线程,提示t1已经完成
- Console.ReadLine();
- }
- }
- }
- /*输出结果:
- *t1 is ending.
- *t1.Join() returned.
- *
- *t2.Join() returned.
- *t2 is ending.
- */
输出结果:
从输出结果上分析可以得出,Join方法将创建的线程插入到了主线程中当执行完后再继续执行主线程,对应到Demo2中是线程t1插入到了主线程中,这样会首先执行t1线程在控制台上打印“t1 is ending”打印完成后t1线程结束,然后继续执行主线程来打印其它的文字。所以我们完全可以说Join方法是将一个线程插入到主线程中,当执行完插入的线程后再继续执行被插入的线程。
结语
线程的优缺点决定了在开发过程中是否使用多线程,另外灵活运行单线程的方法来实现灵活的控制线程,两个Demo使用了线程的基本方法,能够更加深刻的了解它们的使用。下篇博客将会更加深入的讨论线程和线程之间的调用关系,以及如何实现线程间的数据传递及检索。
【.NET线程--进阶(一)】--线程方法详解的更多相关文章
- MySQL服务器线程数的查看方法详解
本文实例讲述了MySQL服务器线程数的查看方法.分享给大家供大家参考,具体如下: mysql重启命令: ? 1 /etc/init.d/mysql restart MySQL服务器的线程数需要在一个合 ...
- (二)线程Thread中的方法详解
1.start() start()方法的作用讲得直白点就是通知"线程规划器",此线程可以运行了,正在等待CPU调用线程对象得run()方法,产生一个异步执行的效果.通过start( ...
- 线程Thread中的方法详解(二)
1.start() start()方法的作用讲得直白点就是通知"线程规划器",此线程可以运行了,正在等待CPU调用线程对象得run()方法,产生一个异步执行的效果.通过start( ...
- “全栈2019”Java多线程第十二章:后台线程setDaemon()方法详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- “全栈2019”Java多线程第七章:等待线程死亡join()方法详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- “全栈2019”Java多线程第六章:中断线程interrupt()方法详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- “全栈2019”Java多线程第五章:线程睡眠sleep()方法详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- java多线程并发(二)--线程的生命周期及方法详解
上篇随笔介绍了线程的相关基础知识以及新启线程的几种方法,本片将继续介绍线程的生命周期及方法详解. 一.线程的生命周期 在Thread代码中,线程的状态被分为6种 public enum State { ...
- 并发编程(六)Object类中线程相关的方法详解
一.notify() 作用:唤醒一个正在等待该线程的锁的线程 PS : 唤醒的线程不会立即执行,它会与其他线程一起,争夺资源 /** * Object类的notify()和notifyAll()方法详 ...
- java线程池的使用与详解
java线程池的使用与详解 [转载]本文转载自两篇博文: 1.Java并发编程:线程池的使用:http://www.cnblogs.com/dolphin0520/p/3932921.html ...
随机推荐
- js之观察者模式
观察者模式: 大体上是, 1.松耦合的代码: 2.一对多的关系: 3.主体状态变化时,所有依赖被通知: 4.主体和观察者互不知晓. 基本上,满足上面四点的,就可以算是观察者模式了.来看一个demo, ...
- HTTP协议 (1)
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议. HTT ...
- PHP对Url中的汉字进行编码和解码
有的新手朋友们对于url编码解码这个概念,或许有点陌生.但是如果这么说,当我们在浏览各大网页时,可能发现有的url里有一些特殊符号比如#号,&号,_号或者汉字等等,那么为了符合url的规范,存 ...
- Python的字符串内建函数(字符串处理)
Python的字符串内建函数这些方法实现了string模块的大部分方法 , 如下表硕士列出了目前字符串内建支持的方法 string = 'XXX' string.capitalize() # 把字符串 ...
- python 全栈开发,Day36(作业讲解(大文件下载以及进度条展示),socket的更多方法介绍,验证客户端链接的合法性hmac,socketserver)
先来回顾一下昨天的内容 黏包现象粘包现象的成因 : tcp协议的特点 面向流的 为了保证可靠传输 所以有很多优化的机制 无边界 所有在连接建立的基础上传递的数据之间没有界限 收发消息很有可能不完全相 ...
- OpenLDAP在win2008上安装配置
业务需要,将企业员工信息统一管理,OpenLdap是目录数据库和一套访问协议组成的系统,适合使用,它有以下特点: LDAP的结构用树来表示 C/S模型,Server用户存储数据,Client为操作目录 ...
- 使用vmware提示无法打开内核设备 \\.\Global\vmx86: 系统找不到指定的文件
问题描述 打开虚拟机时候提示 “vmware没有正常关闭,再次打开使用时蓝屏,在安全模式下再次打开不会蓝屏,但提示“无法打开内核设备 \\.\Global\vmx86: 系统找不到指定的文件,你想要安 ...
- PTA之简单阶乘计算
本题要求实现一个计算非负整数阶乘的简单函数. 时间限制: 400ms 内存限制: 64MB 代码长度限制: 16KB 函数接口定义: int Factorial( const int N ); 其中N ...
- PTA之多项式求值
时间限制: 400ms 内存限制: 64MB 代码长度限制: 16KB 函数接口定义: double f( int n, double a[], double x ); 其中n是多项式的阶数,a[]中 ...
- phpstrom破解
lisence输入 2018/04/09 更新 license server:http://im.js.cn:8888 http://idea.iteblog.com/key.php 2018/0 ...