简单介绍
AutoResetEvent和ManualResetEvent都派生自EventWaitHandle类(该类派生自WaitHandle)。EventWaitHandle构造时可以指定事件触发的方式(EventResetMode枚举),AutoResetEvent和ManualResetEvent只是构造时调用了EventWaitHandle的不同参数的构造方法,即
public AutoResetEvent(bool initialState) : base(initialState, EventResetMode.AutoReset)
{
}

public ManualResetEvent(bool initialState) : base(initialState, EventResetMode.ManualReset)
{
}
从而避免了构造时对具体类名的依赖。


基本用法

1. 定义事件。
2. 在一个线程中设置事件等待(WaitOne、WaitAll、WaitAny)。
3. 在另一个事件中Set事件,让等待线程继续。


简单例子

using System;
using System.Threading;

internal class Test
{
    
private static EventWaitHandle ewh = new EventWaitHandle(false, EventResetMode.AutoReset);

    
public static void Main()
    {
        Thread t1 
= new Thread(Thread1);
        t1.Start();

        Console.WriteLine(
"Start wait 1");
        ewh.WaitOne();
        Console.WriteLine(
"Go through 1");

        Console.WriteLine(
"Start wait 2");
        ewh.WaitOne();
        Console.WriteLine(
"Go through 2");
    }

    
public static void Thread1()
    {
        Thread.Sleep(
1000);

        Console.WriteLine(
"Event Set");
        ewh.Set();
    }
}
如果是AutoResetHandle,那么Set完之后,ewh会重新置为“nonsignaled”的状态,如果要继续等待事件,就必须再次Set。
如果是ManualResetHandle,在Set完之后,状态不会自动重置,而是依然保留“signaled”的状态,那么不必再次Set就可以通过等待事件。可以通过Reset来重置事件到“nonsignaled”状态。

自动重置事件提供对资源的独占访问。如果没有线程等待时自动重置事件处于终止状态,则该事件一直保持终止状态,直到某个线程尝试在该事件上等待。该事件释放线程并立即重置,以阻止后面的线程。
手动重置事件类似于入口。当事件不处于终止状态时,在该事件上等待的线程将阻止。当事件处于终止状态时,所有等待的线程都被释放,而事件一直保持终止状态(即后面的等待不阻止),直到它的 Reset 方法被调用。如果一个线程必须完成一项活动后,其他线程才能继续,则手动重置事件很有用。


各种Wait的区别

WaitOne()以及各种重载,等待当前事件的Set,阻塞当前线程(或者一个指定的时间)。
WaitAll()以及各种重载,静态方法,等待事件数组中所有事件都得到Set。
WaitAny()以及各种重载,静态方法,等待事件数组中任一事件得到Set。

参考:http://www.rainsts.net/article.asp?id=170
http://msdn2.microsoft.com/zh-cn/library/system.threading.eventwaithandle.aspx
posted on 2008-04-16 11:43  Yao Min  阅读(316)  评论(0编辑  收藏  举报