惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Darknet – Hacking Tools, Hacker News & Cyber Security
博客园_首页
T
The Blog of Author Tim Ferriss
罗磊的独立博客
The Register - Security
The Register - Security
IT之家
IT之家
D
Docker
爱范儿
爱范儿
Apple Machine Learning Research
Apple Machine Learning Research
Hugging Face - Blog
Hugging Face - Blog
博客园 - Franky
L
LangChain Blog
J
Java Code Geeks
博客园 - 三生石上(FineUI控件)
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
K
Kaspersky official blog
Latest news
Latest news
博客园 - 聂微东
酷 壳 – CoolShell
酷 壳 – CoolShell
Cyberwarzone
Cyberwarzone
人人都是产品经理
人人都是产品经理
C
CERT Recently Published Vulnerability Notes
The Hacker News
The Hacker News
T
Tailwind CSS Blog
S
SegmentFault 最新的问题
MongoDB | Blog
MongoDB | Blog
Scott Helme
Scott Helme
L
LINUX DO - 热门话题
Spread Privacy
Spread Privacy
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
D
DataBreaches.Net
Project Zero
Project Zero
H
Hackread – Cybersecurity News, Data Breaches, AI and More
G
Google Developers Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
C
Check Point Blog
S
Schneier on Security
NISL@THU
NISL@THU
T
Tor Project blog
P
Proofpoint News Feed
N
News and Events Feed by Topic
Last Week in AI
Last Week in AI
N
Netflix TechBlog - Medium
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
U
Unit 42
C
Cybersecurity and Infrastructure Security Agency CISA
T
The Exploit Database - CXSecurity.com
L
LINUX DO - 最新话题
Help Net Security
Help Net Security
Blog — PlanetScale
Blog — PlanetScale

博客园 - sopper

Visual Assist X设置 转 mac入门系列教程之二–-Mac与众不同(4) 转 mac入门系列教程之二–-Mac与众不同(3) 转 mac入门系列教程之二–-Mac与众不同(2) 转 mac入门系列教程之二–Mac与众不同(1) 转 C++带有指针数组的结构体转换为C#可用的结构体 C#调用C++版本dll时的类型转换要注意的问题 小技巧 瑞星版本20.49.30的Bug C++控件的数据交换和数据校验 VC6类向导对窗体按钮添加的消息映射代码 c/c++下常见的内存错误及其对策 CORBA_TAO的环境配置 - sopper - 博客园 异步socket的线程分配(C#) 你知道main函数参数的用处吗? - sopper - 博客园 你能确定这段代码的输出结果吗? 小技巧避免项目中的大隐患 提给dudu的一个小建议 vc6使用点滴积累
再议ManualResetEvent
sopper · 2008-03-18 · via 博客园 - sopper

        ManualResetEvent就像一个信号灯,可以利用它的信号,控制当前线程是挂起状态还是运行状态。
        它有几个常用的方法:Reset(),Set(),WaitOne();
        初始化该对象时,可以指定其默认的状态(有信号/无信号);
        在初始化以后,该对象将保持原来的状态不变,直到它的Reset()或者Set()方法被调用;
        Reset()方法将其设置为无信号状态,Set()方法将其设置为有信号状态;
        WaitOne()方法在无信号状态下,可以使当前线程挂起;注意这里说的是当前线程;
        直到调用了Set()方法,该线程才被激活。

        在多线程的代码里,可以使用一个ManualResetEvent对象来控制线程所有线程;
        只要在调用WaitOne()方法前,调用Reset()方法,因为WaitOne()控制的是当前线程;
        但是这样做,ManualResetEvent对象的管理逻辑会变得复杂;
        所以这里建议一条线程一个ManualResetEvent对象。
 

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace ConsoleThread
{
    
class ThreadClass
    
{
        
public void threadFun()
        
{
            Thread.Sleep(
1000);
            Console.WriteLine(
"ThreadClass.threadFun 1");

            
//激活被挂起的线程
            Program.allDone.Set();

            Console.WriteLine(
"ThreadClass.threadFun 2");

            
//设置为无信号,如果注释这条语句,
            
//下面的WaitOne()方法就不起做用了
            Program.allDone.Reset();

            
//使当前线程挂起
            Program.allDone.WaitOne();

            Console.WriteLine(
"ThreadClass.threadFun 3");

        }


    }
;
    


    
class Program
    
{
        
public static ManualResetEvent allDone = new ManualResetEvent(false);
        
static void Main(string[] args)
        
{
            Console.WriteLine(
"Thread Start/Stop/Join Sample");
            ThreadClass ThreadC 
= new ThreadClass();
            Thread thread 
= new Thread(new ThreadStart(ThreadC.threadFun));
            thread.Start();

            
//挂起当前线程
            allDone.WaitOne();

            Console.WriteLine(
"Main 1");

            
//因为ThreadClass.threadFun方法里调用了Reset()
            
//所以这里的WaitOne()方法会使主线程也挂起
            
//allDone.WaitOne();

            
//使主线程挂起1秒钟,
            
//为了ThreadClass.threadFun方法里的Program.allDone.WaitOne()方法
            
//运行时间在Main()方法的allDone.Set()方法前面
            Thread.Sleep(5000);

            
//设置为有信号
            
//如果没有这条语句,ThreadClass.threadFun方法里最后一条语句就不会运行
            allDone.Set();
            Console.WriteLine(
"Main 2");
        }

    }

}