线程 ManualResetEvent 类「建议收藏」

线程 ManualResetEvent 类「建议收藏」为了把状态修改为无信号的 必须调用 ReSet 方法 WaitOne 调用 ManualResetE 上的 WaitOne 的线程将阻止 并等待信号 Set 当控制线程完成活动时 它调用 Set 以发出等待线程可以继续进行的信号 并释放所有等待线程 Set 将事件状态设置为终止状态 允许一个或多个等待线程继续 为了把状态修改为有信号的 必须调用 Set 方法

为了把状态修改为无信号的,必须调用ReSet()方法。

WaitOne(): 调用ManualResetEvent 上的 WaitOne 的线程将阻止,并等待信号。

Set ()当控制线程完成活动时,它调用 Set 以发出等待线程可以继续进行的信号。并释放所有等待线程。Set将事件状态设置为终止状态,允许一个或多个等待线程继续。

为了把状态修改为有信号的,必须调用Set()方法。

ManualResetEvent对象只能拥有两种状态之一:有信号(True)或无信号(false)。ManualResetEvent类继承于WaitHandle类,其构造函数的参数可确定对象的初始状态。

Set()和Reset()方法返回一个布尔值,表示是否进行了成功的修改。

using System;


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()方法。

[csharp]
view plain
copy

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()方法后也不用等待。

下面在看一个程序:

[csharp]
view plain
copy

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一直等到有信号 才开始执行下面的语句.

[csharp]
view plain
copy

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方法里面可以放置一个时间期限,单位是毫秒。

编程小号
上一篇 2025-02-05 15:21
下一篇 2025-01-28 15:33

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/hz/142480.html