C#多线程开发2:线程挂起,恢复与中止等操作

2024-04-02 19:38

本文主要是介绍C#多线程开发2:线程挂起,恢复与中止等操作,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在博文《C#多线程开发1:使用Thread类创建与启动线程》中介绍了线程的创建与启动。本文将在前文的基础之上,接着介绍线程的挂起,恢复与中止等操作。

首先回忆一下前文的知识点。

我们已经学习到:

1、创建线程

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

或者

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

线程入口方法:

static void CalcSum()
{//do what you want   
}


2、启动线程

workThread.Start();


接下来,我们来研究线程的其他操作。

此文所用实例是在前文实例的基础上做一点小变动而得到的。

一开始,给出前文的完整实例代码及运行结果(以供整体把握实例操作)。

using System;
using System.Threading;namespace ThreadExample
{class Program{static void Main(string[] args){       ThreadStart entry = new ThreadStart(CalcSum);Thread workThread = new Thread(entry);workThread.Start();CalcGap();}static void CalcSum(){long sum = 0;for (long i = 0; i < 1000000000; i++){sum += i;if (i % 100000000 == 0 && i!=0){Console.WriteLine("workThread-->i={0}:sum={1}",i,sum);}}}static void CalcGap(){long gap = 0;for (long i = 1000000000; i >=0 ; i--){gap = i-1;if (i % 100000000 == 0 && i != 0){Console.WriteLine("MainThread-->i={0}:gap={1}", i, gap);}}}}
}

运行结果:

实例中,存在两个线程,主线程(Main函数)和工作线程(workThread线程),主线程完成求差操作,工作线程完成求和操作。两个线程同时运行。

 

3、挂起线程

挂起线程使用Suspend()方法。

线程被挂起后,操作被停止或进入休眠状态。

被挂起的线程不占用任何处理器时间。

修改前文实例代码,修改部分如下:

ThreadStart entry = new ThreadStart(CalcSum);
Thread workThread = new Thread(entry);
workThread.Start();
workThread.Suspend();//挂起线程(改动部分)
CalcGap();

再次执行程序,得到如下结果:

从结果中可以看出,此时主线程正常执行,但是工作线程workThread没有被执行,因为工作线程一启动后就被挂起了,所以不会被执行。那么要想工作线程能继续执行,就需要恢复线程了。

 

4、恢复线程

线程恢复使用Resume()方法。

再次修改代码。

Thread workThread = new Thread(new ThreadStart(CalcSum));
workThread.Start();
workThread.Suspend();//挂起线程(改动部分)
CalcGap();
workThread.Resume();//恢复线程(改动部分)

上面的代码,在主线程执行完后,恢复被挂起的工作线程,执行结果如下。

对于这个结果,我们是可以预见的。

 

5、中止线程

中止线程使用Abort()方法。

线程被中止,就停止运行,是无法恢复的,因为Windows会永久地删除被中止线程的所有数据。

再次修改代码。

Thread workThread = new Thread(new ThreadStart(CalcSum));
workThread.Start();
workThread.Abort();//中止线程(改动部分)
CalcGap();

执行结果如下:

跟挂起工作线程时的结果一样,中止工作线程后,工作线程自然不会被执行。

我们自作聪明一把,尝试着去恢复被中止的线程,看看会有什么样的结果?

修改代码:

Thread workThread = new Thread(new ThreadStart(CalcSum));
workThread.Start();
workThread.Abort();
CalcGap();
workThread.Resume();//改动代码

运行程序,出现运行时错误,提示:

线程目前未运行;无法使其继续。

这点可以理解。

 

6、使线程休眠

使线程休眠使用Sleep()方法(看着就想睡觉)。

我们还可以使线程休眠一定的时间,累了就让他歇歇再工作。

示例代码如下:

Thread workThread = new Thread(new ThreadStart(CalcSum));
workThread.Start();
Thread.Sleep(10000);//修改代码
CalcGap();

执行结果:

从结果可以看出,主线程会被暂停一段时间后再接着运行,因为他去睡觉去了,睡了多久,睡了10000ms。休眠线程无需恢复,到指定时间会自动执行,他是不会睡到自然醒的哦。

 

7.Join()方法等待线程中止

如果后续的处理依赖于另一个已经终止的线程,可以调用Join()方法,等待线程中止。

修改代码:

Thread workThread = new Thread(new ThreadStart(CalcSum));
workThread.Start();
workThread.Join();//等待工作线程中止(修改代码)
CalcGap();

运行结果:

工作线程调用了Jion()方法,需待工作线程中止后,主线程才会被执行。

Jion()的其他重载方法可以指定等待的时间期限,超过了这个时间期限,程序也会继续执行。

示例代码:

Thread workThread = new Thread(new ThreadStart(CalcSum));
workThread.Start();
workThread.Join(10000);//修改代码
CalcGap();

结果:

主线程会等待一段时间(10000ms),若这段时间内工作线程没挂掉,一旦超过这个时间,主线程便会开始工作。

Ok,就到这里了。

这篇关于C#多线程开发2:线程挂起,恢复与中止等操作的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/870876

相关文章

Agent开发核心技术解析以及现代Agent架构设计

《Agent开发核心技术解析以及现代Agent架构设计》在人工智能领域,Agent并非一个全新的概念,但在大模型时代,它被赋予了全新的生命力,简单来说,Agent是一个能够自主感知环境、理解任务、制定... 目录一、回归本源:到底什么是Agent?二、核心链路拆解:Agent的"大脑"与"四肢"1. 规划模

C#借助Spire.XLS for .NET实现在Excel中添加文档属性

《C#借助Spire.XLSfor.NET实现在Excel中添加文档属性》在日常的数据处理和项目管理中,Excel文档扮演着举足轻重的角色,本文将深入探讨如何在C#中借助强大的第三方库Spire.... 目录为什么需要程序化添加Excel文档属性使用Spire.XLS for .NET库实现文档属性管理Sp

Go异常处理、泛型和文件操作实例代码

《Go异常处理、泛型和文件操作实例代码》Go语言的异常处理机制与传统的面向对象语言(如Java、C#)所使用的try-catch结构有所不同,它采用了自己独特的设计理念和方法,:本文主要介绍Go异... 目录一:异常处理常见的异常处理向上抛中断程序恢复程序二:泛型泛型函数泛型结构体泛型切片泛型 map三:文

JAVA线程的周期及调度机制详解

《JAVA线程的周期及调度机制详解》Java线程的生命周期包括NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING和TERMINATED,线程调度依赖操作系统,采用抢占... 目录Java线程的生命周期线程状态转换示例代码JAVA线程调度机制优先级设置示例注意事项JAVA线程

C++,C#,Rust,Go,Java,Python,JavaScript的性能对比全面讲解

《C++,C#,Rust,Go,Java,Python,JavaScript的性能对比全面讲解》:本文主要介绍C++,C#,Rust,Go,Java,Python,JavaScript性能对比全面... 目录编程语言性能对比、核心优势与最佳使用场景性能对比表格C++C#RustGoJavapythonjav

C# 预处理指令(# 指令)的具体使用

《C#预处理指令(#指令)的具体使用》本文主要介绍了C#预处理指令(#指令)的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录1、预处理指令的本质2、条件编译指令2.1 #define 和 #undef2.2 #if, #el

C#实现将Excel工作表拆分为多个窗格

《C#实现将Excel工作表拆分为多个窗格》在日常工作中,我们经常需要处理包含大量数据的Excel文件,本文将深入探讨如何在C#中利用强大的Spire.XLSfor.NET自动化实现Excel工作表的... 目录为什么需要拆分 Excel 窗格借助 Spire.XLS for .NET 实现冻结窗格(Fro

C# Semaphore与SemaphoreSlim区别小结

《C#Semaphore与SemaphoreSlim区别小结》本文主要介绍了C#Semaphore与SemaphoreSlim区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录一、核心区别概览二、详细对比说明1.跨进程支持2.异步支持(关键区别!)3.性能差异4.API 差

C# List.Sort四种重载总结

《C#List.Sort四种重载总结》本文详细分析了C#中List.Sort()方法的四种重载形式及其实现原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友... 目录1. Sort方法的四种重载2. 具体使用- List.Sort();- IComparable

C#中Trace.Assert的使用小结

《C#中Trace.Assert的使用小结》Trace.Assert是.NET中的运行时断言检查工具,用于验证代码中的关键条件,下面就来详细的介绍一下Trace.Assert的使用,具有一定的参考价值... 目录1、 什么是 Trace.Assert?1.1 最简单的比喻1.2 基本语法2、⚡ 工作原理3