C# Thread挂起线程和恢复线程
前言
众所周知,Thread类中的挂起线程和恢复线程微软已标记过时,因为可能会造成问题
Resume() 恢复当前线程 |
已过时。 Resumes a thread that has been suspended. |
Suspend() 挂起当前线程 |
已过时。 挂起线程,或者如果线程已挂起,则不起作用。 |
其他方式实现
一、ThreadWorkItem
class ThreadWorkItem
{
public int ThreadManagerId { get; set; }
public Thread Thread { get; set; }
public string ThreadName { get; set; }
public bool Flag { get; set; }
public ManualResetEvent ManualResetEvent { get; set; } }
二、C# Thread挂起线程和恢复线程的实现的两种方式
方式1:使用变量开关控制挂起线程和恢复线程,具体代码如下
public class Program
{
//线程工作集合
private static List<ThreadWorkItem> Works = new List<ThreadWorkItem>(); //方式1:使用变量开关控制挂起线程和恢复线程 private static void Main(string[] args)
{
ThreadWorkItem wItem = null;
Thread t = null; var threadNum = ; for (int i = ; i < threadNum; i++)
{ t = new Thread(o=>
{
var w = o as ThreadWorkItem;
if (w == null) return;
while (true)
{
if (!w.Flag)
{
Console.WriteLine("我是线程:" + Thread.CurrentThread.Name);
Thread.Sleep();
continue;
}
//避免CPU空转
Thread.Sleep(); } });
//$ C#6.0语法糖
t.Name = $"Hello I'am 线程:{i}-{t.ManagedThreadId}";
wItem = new ThreadWorkItem
{
Flag = false,
Thread = t,
ThreadManagerId = t.ManagedThreadId,
ThreadName = t.Name
};
Works.Add(wItem);
t.Start(Works[i]);
} //5秒后允许一个等待的线程继续。当前允许的是线程1
Thread.Sleep();
Works[].Flag = true;
Console.WriteLine($"thread-{Works[0].ThreadName} is 暂停"); //5秒后允许一个等待的线程继续。当前允许的是线程0,1
Thread.Sleep();
Works[].Flag = false;
Console.WriteLine($"thread-{Works[0].ThreadName} is 恢复"); }
}
方式2:使用ManualResetEvent控制挂起线程和恢复线程(推荐);替代Thread类中被微软标记过时的函数(内核模式非混合模式)
public class Program
{
//线程工作集合
static List<ThreadWorkItem> Works = new List<ThreadWorkItem>(); //方式2:使用ManualResetEvent控制挂起线程和恢复线程(推荐);替代Thread类中被微软标记过时的函数
static void Main(string[] args)
{ Task.Factory.StartNew(() =>
{
Thread t = null;
ThreadWorkItem item = null;
for (int i = ; i < ; i++)
{
t = new Thread((o) =>
{
var w = o as ThreadWorkItem;
if (w == null) return; while (true)
{
//阻塞当前线程
w.ManualResetEvent.WaitOne(); Console.WriteLine("我是线程:" + Thread.CurrentThread.Name);
Thread.Sleep();
} });
t.Name = "Hello,i 'am Thread: " + i;
item = new ThreadWorkItem
{
//线程0,1持续运行,设置true后非阻塞,持续运行。需要手动触发Reset()才会阻塞实例所在当前线程
ManualResetEvent = new ManualResetEvent(true),
Thread = t,
ThreadManagerId = t.ManagedThreadId,
ThreadName = t.Name
};
Works.Add(item);
t.Start(item);
} //5秒后准备暂停一个线程1。线程0持续运行 Thread.Sleep();
Console.WriteLine("close...");
Works[].ManualResetEvent.Reset(); //5秒后恢复线程1;线程0,1持续运行
Thread.Sleep();
Console.WriteLine("open...");
Works[].ManualResetEvent.Set(); //5秒后准备暂停一个线程0。线程1持续运行
Thread.Sleep();
Console.WriteLine("close0...");
Works[].ManualResetEvent.Reset(); //5秒后恢复线程1;线程0,1持续运行
Thread.Sleep();
Console.WriteLine("open0...");
Works[].ManualResetEvent.Set(); }); Console.ReadLine();
} }
三、总结
1.有时候会觉得必须由主线程创建ManualResetEvent实例才能起到作用,实际并不是这样的,上述方式2则证明了这一点。
2.那么AutoResetEvent做不到同样的效果吗?
答:AutoResetEvent 顾名思义,自动Reset()表示重置信号量状态,当前线程中持有WaitOne()就又会被持续阻塞。而ManualResetEvent必须要手动调用Reset()才能重置信号量,这里再解释下Set(),它表明允许一个或多个被同一个ManualResetEvent实例WaitOne()的线程放行。
3.实例化信号量的构造参数是什么意思?
答:信号量非终止状态,如果值为false则表明终止状态,调用WaitOne()方法的时候立即阻塞。设置true可以理解为隐式调用了Set()方法放行一次。
4. ManualResetEvent和AutoResetEvent的区别
答:ManualResetEvent调用Set()允许一个或多个被同一个ManualResetEvent实例WaitOne()的线程放行。
AutoResetEvent调用Set() 只能允许一个线程放行。如果多处使用同一个实例,则需要手动调用多次Set()
C# Thread挂起线程和恢复线程的更多相关文章
- MFC中挂起线程和恢复线程
DWORD SuspendThread ( HANDLE hThread ); //挂起线程DWORD ResumeThread ( HANDLE hThread ); //恢复线程 比如说我 ...
- Java并发之线程管理(线程基础知识)
因为书中涵盖的知识点比较全,所以就以书中的目录来学习和记录.当然,学习书中知识的时候自己的思考和实践是最重要的.说到线程,脑子里大概知道是个什么东西,但很多东西都还是懵懵懂懂,这是最可怕的.所以想着细 ...
- iOS边练边学--多线程NSOperation介绍,子类实现多线程的介绍(任务和队列),队列的取消、暂停(挂起)和恢复,操作依赖与线程间的通信
一.NSOperation NSOperation和NSOperationQueue实现多线程的具体步骤 先将需要执行的操作封装到一个NSOperation对象中 然后将NSOperation对象添加 ...
- java线程技术6_线程的挂起和唤醒[转]
转自:http://blog.chinaunix.net/uid-122937-id-215913.html 1. 线程的挂起和唤醒 挂起实际上是让线程进入“非可执行”状态下,在这个状态下C ...
- 使用 suspend 和 resume 暂停和恢复线程
suspend 和 resume 的使用 在 Thread 类中有这样两个方法:suspend 和 resume,这两个方法是成对出现的. suspend() 方法的作用是将一个线程挂起(暂停), r ...
- java基础知识回顾之java Thread类学习(十)--线程的状态以及转化使用的方法介绍
线程的概述: 线程是程序的多个执行路径,执行调度的单位,依托于进程存在.线程不仅可以共享进程的内存,而且还拥有一个属于自己的内存空间,这段内存空间叫做线程栈,是建立线程的时候由系 ...
- Java Thread.interrupt 害人! 中断JAVA线程(zz)
http://www.blogjava.net/jinfeng_wang/archive/2012/04/22/196477.html#376322 ————————————————————————— ...
- 14.6.8 Configuring the InnoDB Master Thread IO Rate 配置InnoDB 主线程IO 速率:
14.6.8 Configuring the InnoDB Master Thread IO Rate 配置InnoDB 主线程IO 速率: 主线程 在InnoDB 是一个线程 执行各种任务在后台. ...
- C# 显式创建线程 or 使用线程池线程--new Thread() or ThreadPool.QueueUserWorkItem()
在C#多线程编程中,关于是使用自己创建的线程(Thread)还是使用线程池(ThreadPool)线程,一直很困惑,知道看了Jeffrey Richter的相关介绍才明白,记录如下: 当满足一下任何条 ...
随机推荐
- python 学习笔记6(数据库 sqlite)
26. SQLite 轻量级的关系型数据库 SQLite是python自带的数据库,可以搭配python存储数据,开发网站等. 标准库中的 sqlite3 提供该数据库的接口. 1. 基本语法如下 c ...
- Java RTTI机制与反射机制
1.1 什么是RTTI? 维基百科的定义:In computer programming, RTTI (Run-Time Type Information, or Run-Time Type Iden ...
- 【BZOJ-4518】征途 DP + 斜率优化
4518: [Sdoi2016]征途 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 230 Solved: 156[Submit][Status][ ...
- Java反射机制的作用
假如我们有两个程序员,一个程序员在写程序的时候,需要使用第二个程序员所写的类,但第二个程序员并没完成他所写的类.那么第一个程序员的代码能否通过编译呢?这是不能通过编译的.利用Java反射的机制,就可以 ...
- Oracle技术嘉年华
只有把一件事情做好,才会获得更多的机会! 短期的努力,成效并不明显,但是自己的成长一定能够感受到! 嘉年华的收获: 遗憾: 总结: 展望:
- mtd零星记录
查看Flash分区情况: root@DD-WRT:~# cat /proc/mtd dev: size erasesize name mtd0: "RedBoot" mtd1: 0 ...
- JS, Node.js, npm简介
序 听过JS,听过Node,也听过Node.js,还听过npm,然而并不是很清楚的知道都代表什么,这两天调接口,然后前端同学很忙,就自己把前端代码拿过来跑了,也趁机了解一下这几个概念,下边做个小的总结 ...
- linux下history命令显示历史指令记录的使用方法
Linux系统当你在shell(控制台)中输入并执行命令时,shell会自动把你的命令记录到历史列表中,一般保存在用户目录下的.bash_history文件中.默认保存1000条,你也可以更改这个值 ...
- linux cat 的深入用法
命令基于centos6系列,翻译基于官方原文的意思. catcat - concatenatefiles 1117.www.qixoo.qixoo.com and print on the stand ...
- MooseFs-分布式文件系统系列(一)之了解并安装它
preface 在上上家公司,曾维护过公司的MFS文件系统,主要用来存储系统日志文件,单纯的把日志当作文件存储,在当时的架构下,MFS就像一个中间站一样,这边程序生成的日志放入MFS,那边日志分析程序 ...