线程 ManualResetEvent 类
来源:互联网 发布:php开发工具 编辑:程序博客网 时间:2024/06/06 01:59
Reset(): 当一个线程开始一个活动(此活动必须完成后,其他线程才能开始)时, 它调用 Reset 以将 ManualResetEvent 置于非终止状态。此线程可被视为控制 ManualResetEvent。
为了把状态修改为无信号的,必须调用ReSet()方法。
WaitOne(): 调用ManualResetEvent 上的 WaitOne 的线程将阻止,并等待信号。
Set ()当控制线程完成活动时,它调用 Set 以发出等待线程可以继续进行的信号。并释放所有等待线程。Set将事件状态设置为终止状态,允许一个或多个等待线程继续。
为了把状态修改为有信号的,必须调用Set()方法。
ManualResetEvent对象只能拥有两种状态之一:有信号(True)或无信号(false)。ManualResetEvent类继承于WaitHandle类,其构造函数的参数可确定对象的初始状态。
Set()和Reset()方法返回一个布尔值,表示是否进行了成功的修改。
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace ManualResetshiyan
...{
class Program
...{
static void Main(string[] args)
...{
ManualResetEvent mansig;
mansig = new ManualResetEvent(false);
Console.WriteLine("ManualResetEvent Before WaitOne");
bool b = mansig.WaitOne(1000, true);
Console.WriteLine("ManualResetEvent After WaitOne" + b);
Console.ReadLine();
}
}
}
上面的例子中,构造了false值的ManualResetEvent对象,布尔值False把ManualResetEvent对象的初始状态设置为无信号。接着调用基类WaigHandle的WaitOne()方法。程序块在WaitOne()方法中暂停一秒,然后因为超时而退出。ManualResetEvent的状态仍然是False,因而WaitOne()返回的布尔值b是False。
下面的例子把有信号改为无信号,调用ReSet()方法,Set()方法。
using System;using System.Collections.Generic;using System.Text;using System.Threading;namespace 同步{ class Program { static void Main(string[] args) { ManualResetEvent mansig; mansig = new ManualResetEvent(true); bool state = mansig.WaitOne(9000, true); Console.WriteLine("ManualResetEvent After WaitOne" + state); mansig.Reset(); state = mansig.WaitOne(9000, true); Console.WriteLine("ManualResetEvent After WaitOne" + state); mansig.Set(); state = mansig.WaitOne(9000, true); Console.WriteLine("ManualResetEvent After WaitOne" + state); } }}
在ManualReset中,MnualTResetEvent对象的构造函数将其状态设置为有信号(true),结果,线程不在第一个
WaitOne()方法中等待,并返回True值。接着,ManualResetEvent对象的状态重新设置为无信号的(false),于是线程在超时之前必须等待5秒,调用Set()方法后也不用等待。
下面在看一个程序:
using System;using System.Collections.Generic;using System.Text;using System.Threading;namespace 同步实验{ class Program { /// /// ManualResetEvent建立时是把false作为start的初始状态,这个类用于通知另一个线程,让它等待一个或多个线程。 /// 如这个例子中,等待线程thread1线程调用mre.WaitOne(), 用于发信号的线程调用mre.Set(). /// public static ManualResetEvent mre = new ManualResetEvent(false); public static void trmain() { Thread tr = Thread.CurrentThread; Console.WriteLine(tr.Name + " 开始第一波等待"); mre.WaitOne(); //等到什么时候呢?等到mre.Set()被调用 Console.WriteLine(tr.Name + " 第一波启动t"); mre.Reset(); //再次重置 Console.WriteLine(tr.Name + " 开始第二波等待"); mre.WaitOne(); //再次等待 Console.WriteLine(tr.Name + " 第二波启动"); for (int x = 0; x < 10; x++) { Thread.Sleep(1000); Console.WriteLine(tr.Name + ": " + x); } } static void Main(string[] args) { Thread thrd1 = new Thread(new ThreadStart(trmain)); thrd1.Name = "thread1"; thrd1.Start(); Thread thrd2 = new Thread(new ThreadStart(trmain)); thrd2.Name = "thread2"; thrd2.Start(); for (int x = 0; x < 10; x++) { Thread.Sleep(900); Console.WriteLine("Main :" + x); if (5 == x) { mre.Set(); //子线程的mre.WaitOne()可以执行了。第一次等待进程 //; //如果什么都不做呢,mre.Wait()那个线程就一直等在那里了? } } while (thrd1.IsAlive) { Thread.Sleep(1000); Console.WriteLine("Main: waiting for thread to stop..."); mre.Set(); //第二次通知等待进程 } } } }
下面在看一个关于ManualResetEvent waitany的程序:
waitany一直等到有信号 才开始执行下面的语句.
using System;using System.Collections.Generic;using System.Text;using System.Threading;namespace 同步实验{ class Program { public static ManualResetEvent m_eventTemporaryTrigger; public static ManualResetEvent m_eventQuitTemporary; private static string m_triggerParam; public static void TemporaryConnThreadTrigger(String param) { m_triggerParam = param; m_eventTemporaryTrigger.Set(); } static void Main(string[] args) { m_eventTemporaryTrigger =new ManualResetEvent(true); m_eventQuitTemporary = new ManualResetEvent(true); //m_eventQuitTemporary = new ManualResetEvent(false); m_eventTemporaryTrigger.Reset(); //临时线程处于工作之中时,m_eventTemporaryTrigger始终处于被触发状态 // Trigger.strmain(); WaitHandle[] events = new WaitHandle[2]; events[0] = m_eventQuitTemporary; events[1] = m_eventTemporaryTrigger; //等待退出信号事件或触发事件 // 返回结果: // 满足等待的对象的数组索引。 int index = WaitHandle.WaitAny(events); Console.WriteLine("run no wait"); if (index == 0) {//如果是将Main(),第三行置为false则不执行下面语句 Console.WriteLine("m_eventQuitTemporary run"); Console.WriteLine(m_triggerParam); } } } public class Trigger { public static void strmain() { Program.TemporaryConnThreadTrigger("m_eventQuitTemporary run show"); } }}
要注意的是ManualResetEvent和AutoResetEvent 的构造函数都有一个bool的参数,用这个参数可以指定初始情况下,同步对象的处于阻塞(设置为false)还是非阻塞(设置为true)的状态。
另外WaitOne方法也可以带两个参数:
WaitOne (int millisecondsTimeout,bool exitContext)
millisecondsTimeout:等待的毫秒数,或为 Timeout.Infinite (-1),表示无限期等待。
exitContext:为 true,则等待之前先退出上下文的同步域(如果在同步上下文中),然后在稍后重新获取它;否则为false。
就是说,等待是可以加上一个期限的,如果等待的同步对象一直都不Set()的话,那么程序就会卡死,所以在WaitOne方法里面可以放置一个时间期限,单位是毫秒。
- 线程 ManualResetEvent 类
- 线程 ManualResetEvent 类
- ManualResetEvent,AutoResetEvent类线程同步
- 线程间通信 ManualResetEvent
- 线程同步 ManualResetEvent
- ManualResetEvent 线程同步
- 线程同步- EventWaitHandle类的子类ManualResetEvent的用法
- 线程同步 - EventWaitHandle & AutoResetEvent & ManualResetEvent
- AutoResetEvent和ManualResetEvent 线程同步
- 线程同步:ManualResetEvent和AutoResetEvent
- ManualResetEvent类的用法
- 多线程信号类ManualResetEvent
- ManualResetEvent
- ManualResetEvent
- ManualResetEvent
- ManualResetEvent
- ManualResetEvent
- ManualResetEvent
- 在linux系统中,执行php脚本
- 紧急求自动登陆程序代码
- 用Resources类为从类路径中加载资源
- Java访问数据库的速度瓶颈问题的分析及解决
- 已经落后了!
- 线程 ManualResetEvent 类
- Framebuffer objects
- 老技術應用——DOS命令增加靜態路由
- 怎样开发linux内核(HOWTO do Linux kernel development - take 3 (中文版))
- 小公司能开发世界级的产品,建立世界级的IT开发团队吗? :::IT技术管理系列之一:::
- Java容器类List、ArrayList、Vector及map、HashTable、HashMap的区别
- GIF解码和编码操作库源码(转载)
- 2008-5-25
- 心悬