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的相关介绍才明白,记录如下: 当满足一下任何条 ...
随机推荐
- 将代码托管到OSChina服务器上
前言:前面的文章已经介绍过了如何将代码托管到github的服务器.并且笔者也详细的介绍了使用HTTPS和SSH两种不同的身份验证方式.但是仅仅介绍github的使用是不够的,原因笔者已经在前面的文章中 ...
- Win7下完全卸载Oracle 11g的步骤
1 右击“计算机”-->管理-->服务和应用程序-->服务,停掉所有Oracle相关的服务(以Oracle打头的,比如OracleDBConsoleorcl). 2 开始--> ...
- 【BZOJ-2502】清理雪道 有上下界的网络流(有下界的最小流)
2502: 清理雪道 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 594 Solved: 318[Submit][Status][Discuss] ...
- 【bzoj3674】 可持久化并查集加强版
http://www.lydsy.com/JudgeOnline/problem.php?id=3674 (题目链接) 题意 维护并查集3个操作:合并:回到完成第k个操作后的状态:查询. Soluti ...
- 【bzoj1086】 scoi2005—王室联邦
http://www.lydsy.com/JudgeOnline/problem.php?id=1086 (题目链接) 题意 求将树分为几个联通块,每个联通块大小大于B小于3B,是否可行. Solut ...
- css选择器(选择<div>内所有<p>元素)
情况1:<div><p></div> 情况2:<div><a><p></p></a></div&g ...
- 微信公众平台教程和SDK收集
教程收集: 1.Senparc(.net) http://www.cnblogs.com/szw/archive/2013/05/14/weixin-course-index.html 2.方倍工作室 ...
- Flipping Bits in Memory Without Accessing Them: An Experimental Study of DRAM Disturbance Errors
目录 . Rowhammer Introduction . Rowhammer Principle . Track And Fix 1. rowhammer introduction 今天的DRAM ...
- Fckeditor PHP/ASP File Upload Vul
目录 . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 FCKeditor是目前最优秀的可见即可得网页编辑器之一,它采用JavaScrip ...
- 通过broadcastreceiver 监听短信问题
在mainfest中 订阅 短信到来的广播时候 发现找不到 <action android:name="android.provider.Telephony.SMS_RECEIV ...