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的相关介绍才明白,记录如下: 当满足一下任何条 ...
随机推荐
- 【CCCC天梯赛决赛】
cccc的天梯赛决赛,水题一样的水,中档题以上的还是没做出来.补了一下题,觉得其实也不是很难,主要是练的少. L2-1:红色预警 并查集 我做的时候想不到并查集,想到了也不一定做的出来,都是其实不难. ...
- 算法与数据结构之交换(SWAP)排序
#include<stdio.h> #include<stdlib.h> void swap(int x,int y); void swap_p(int *px,int *py ...
- css 数字出现滚动条解决
<div style="height:100px;overflow-y:auto;word-wrap:break-word;word-break:break-all;" ng ...
- Bzoj3524 [Poi2014]Couriers
Description 给一个长度为n的序列a.1≤a[i]≤n. m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大于(r-l+1)/2.如果存在,输出这个数,否则输出0 ...
- Process Kill Technology && Process Protection Against In Linux
目录 . 引言 . Kill Process By Kill Command && SIGNAL . Kill Process By Resource Limits . Kill Pr ...
- hihoCoder #1164 随机斐波那契
时间限制:5000ms单点时限:1000ms内存限制:256MB描述 大家对斐波那契数列想必都很熟悉: $a_0 = 1, a_1 = 1, a_i = a_{i-1} + a_{i-2}, (i & ...
- range和xrange梳理
一.python2.7 range 用户获取指定范围内的数,range([start,] stop[, step]) >>> range(1,5) #代表从1到5(不包含5) [1, ...
- http+mysql结合keepalived做热备
preface 公司要求http+mysql+redis+二次开发的ldap要求做高可用,所以此处写写keepalived在这种 环境下的高可用.keepalived这个软件我就不啰嗦了,众所周知,基 ...
- jQuery 基础(4)jQuery 尺寸
jQuery 尺寸方法jQuery 提供多个处理尺寸的重要方法:width()height()innerWidth()innerHeight()outerWidth()outerHeight()jQu ...
- 从Paxos到ZooKeeper-二、ZooKeeper和Paxos
ZooKeeper为分布式应用提供了高效且可靠的分布式协调服务,提供了诸如tong'yi统一命名服务.配置管理和分布式锁等分布式的基础服务.在解决分布式数据一致性方面,ZooKeeper并没有直接采用 ...