.NET Framework 類別庫
ManualResetEvent 類別

更新:2007 年 11 月

告知一個以上的等候中執行緒已發生事件。這個類別無法被繼承。

命名空間:  System.Threading
組件:  mscorlib (在 mscorlib.dll 中)

語法

Visual Basic (宣告)
<ComVisibleAttribute(True)> _
<HostProtectionAttribute(SecurityAction.LinkDemand, Synchronization := True,  _
    ExternalThreading := True)> _
Public NotInheritable Class ManualResetEvent _
    Inherits EventWaitHandle
Visual Basic (使用方式)
Dim instance As ManualResetEvent
C#
[ComVisibleAttribute(true)]
[HostProtectionAttribute(SecurityAction.LinkDemand, Synchronization = true, 
    ExternalThreading = true)]
public sealed class ManualResetEvent : EventWaitHandle
Visual C++
[ComVisibleAttribute(true)]
[HostProtectionAttribute(SecurityAction::LinkDemand, Synchronization = true, 
    ExternalThreading = true)]
public ref class ManualResetEvent sealed : public EventWaitHandle
J#
/** @attribute ComVisibleAttribute(true) */
/** @attribute HostProtectionAttribute(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true) */
public final class ManualResetEvent extends EventWaitHandle
JScript
public final class ManualResetEvent extends EventWaitHandle
備註

注意事項:

套用至這個型別或成員的 HostProtectionAttribute 屬性 (Attribute) 具有下列 Resources 屬性 (Property) 值:Synchronization | ExternalThreadingHostProtectionAttribute 不會影響桌面應用程式 (這些應用的啟動方式一般都是按兩下圖示、輸入命令或在瀏覽器輸入 URL)。如需詳細資訊,請參閱 HostProtectionAttribute 類別或 SQL Server 程式設計和主機保護屬性

在 .NET Framework 2.0 版中,ManualResetEvent 是衍生自新的 EventWaitHandle 類別。ManualResetEvent 的功能等於以 EventResetMode..::.ManualReset 建立的 EventWaitHandle

注意事項:

ManualResetEvent 類別不同的是,EventWaitHandle 類別會提供具名系統同步處理事件的存取權。

ManualResetEvent 能讓執行緒以信號相互通訊。通常這個通信是有關執行緒必須先完成的工作,其他執行緒才能繼續。

如果必須要先完成執行緒開始的活動後,其他執行緒才能夠繼續執行,則它會呼叫 Reset,讓 ManualResetEvent 處於未收到信號的狀態。這個執行緒相當於在控制 ManualResetEvent。執行緒一旦呼叫 ManualResetEvent 上的 WaitOne 就會暫停執行,等候信號。負責控制的執行緒完成活動時,就會呼叫 Set,表示正在等候的執行緒繼續執行。所有正在等候的執行緒都會獲得釋放。

一旦呈信號狀態,ManualResetEvent 就一直呈信號狀態,除非以手動方式重設。也就是亦立即傳回 WaitOne 的呼叫。

您可以向建構函式傳遞布林值以控制 ManualResetEvent 的初始狀態,如果初始狀態是信號狀態,則為 true,否則為 false

ManualResetEvent 也可以與 staticWaitAllWaitAny 方法一起使用。

如需同步處理機制的詳細資訊,請參閱概念文件中的 ManualResetEvent

範例

下列程式碼範例會示範如何使用等候處理常式 (Wait Handle),在不同的複雜數字計算階段完成時,以信號表示。計算的形式為:結果 = 第一期 + 第二期 + 第三期,其中每一期都需要使用計算出的基底數字做預先計算和最終計算。

Visual Basic
Imports System
Imports System.Threading

Public Class CalculateTest

    <MTAThreadAttribute> _
    Shared Sub Main()
        Dim calc As New Calculate()
        Console.WriteLine("Result = {0}.", _
            calc.Result(234).ToString())
        Console.WriteLine("Result = {0}.", _
            calc.Result(55).ToString())
    End Sub
End Class

Public Class Calculate

    Dim baseNumber, firstTerm, secondTerm, thirdTerm As Double
    Dim autoEvents() As AutoResetEvent
    Dim manualEvent As ManualResetEvent

    ' Generate random numbers to simulate the actual calculations.
    Dim randomGenerator As Random 

    Sub New()
        autoEvents = New AutoResetEvent(2) { _
            New AutoResetEvent(False), _
            New AutoResetEvent(False), _
            New AutoResetEvent(False) }

        manualEvent = New ManualResetEvent(False)
    End Sub

    Private Sub CalculateBase(stateInfo As Object)
        baseNumber = randomGenerator.NextDouble()

        ' Signal that baseNumber is ready.
        manualEvent.Set()
    End Sub

    ' The following CalculateX methods all perform the same
    ' series of steps as commented in CalculateFirstTerm.

    Private Sub CalculateFirstTerm(stateInfo As Object)

        ' Perform a precalculation.
        Dim preCalc As Double = randomGenerator.NextDouble()

        ' Wait for baseNumber to be calculated.
        manualEvent.WaitOne()

        ' Calculate the first term from preCalc and baseNumber.
        firstTerm = preCalc * baseNumber * _
            randomGenerator.NextDouble()

        ' Signal that the calculation is finished.
        autoEvents(0).Set()
    End Sub

    Private Sub CalculateSecondTerm(stateInfo As Object)
        Dim preCalc As Double = randomGenerator.NextDouble()
        manualEvent.WaitOne()
        secondTerm = preCalc * baseNumber * _
            randomGenerator.NextDouble()
        autoEvents(1).Set()
    End Sub

    Private Sub CalculateThirdTerm(stateInfo As Object)
        Dim preCalc As Double = randomGenerator.NextDouble()
        manualEvent.WaitOne()
        thirdTerm = preCalc * baseNumber * _
            randomGenerator.NextDouble()
        autoEvents(2).Set()
    End Sub

    Function Result(seed As Integer) As Double

        randomGenerator = New Random(seed)

        ' Simultaneously calculate the terms.
        ThreadPool.QueueUserWorkItem(AddressOf CalculateBase)
        ThreadPool.QueueUserWorkItem(AddressOf CalculateFirstTerm)
        ThreadPool.QueueUserWorkItem(AddressOf CalculateSecondTerm)
        ThreadPool.QueueUserWorkItem(AddressOf CalculateThirdTerm)

        ' Wait for all of the terms to be calculated.
        WaitHandle.WaitAll(autoEvents)

        ' Reset the wait handle for the next calculation.
        manualEvent.Reset()

        Return firstTerm + secondTerm + thirdTerm
    End Function

End Class
C#
using System;
using System.Threading;

class CalculateTest
{
    static void Main()
    {
        Calculate calc = new Calculate();
        Console.WriteLine("Result = {0}.", 
            calc.Result(234).ToString());
        Console.WriteLine("Result = {0}.", 
            calc.Result(55).ToString());
    }
}

class Calculate
{
    double baseNumber, firstTerm, secondTerm, thirdTerm;
    AutoResetEvent[] autoEvents;
    ManualResetEvent manualEvent;

    // Generate random numbers to simulate the actual calculations.
    Random randomGenerator;

    public Calculate()
    {
        autoEvents = new AutoResetEvent[]
        {
            new AutoResetEvent(false),
            new AutoResetEvent(false),
            new AutoResetEvent(false)
        };

        manualEvent = new ManualResetEvent(false);
    }

    void CalculateBase(object stateInfo)
    {
        baseNumber = randomGenerator.NextDouble();

        // Signal that baseNumber is ready.
        manualEvent.Set();
    }

    // The following CalculateX methods all perform the same
    // series of steps as commented in CalculateFirstTerm.

    void CalculateFirstTerm(object stateInfo)
    {
        // Perform a precalculation.
        double preCalc = randomGenerator.NextDouble();

        // Wait for baseNumber to be calculated.
        manualEvent.WaitOne();

        // Calculate the first term from preCalc and baseNumber.
        firstTerm = preCalc * baseNumber * 
            randomGenerator.NextDouble();

        // Signal that the calculation is finished.
        autoEvents[0].Set();
    }

    void CalculateSecondTerm(object stateInfo)
    {
        double preCalc = randomGenerator.NextDouble();
        manualEvent.WaitOne();
        secondTerm = preCalc * baseNumber * 
            randomGenerator.NextDouble();
        autoEvents[1].Set();
    }

    void CalculateThirdTerm(object stateInfo)
    {
        double preCalc = randomGenerator.NextDouble();
        manualEvent.WaitOne();
        thirdTerm = preCalc * baseNumber * 
            randomGenerator.NextDouble();
        autoEvents[2].Set();
    }

    public double Result(int seed)
    {
        randomGenerator = new Random(seed);

        // Simultaneously calculate the terms.
        ThreadPool.QueueUserWorkItem(
            new WaitCallback(CalculateBase));
        ThreadPool.QueueUserWorkItem(
            new WaitCallback(CalculateFirstTerm));
        ThreadPool.QueueUserWorkItem(
            new WaitCallback(CalculateSecondTerm));
        ThreadPool.QueueUserWorkItem(
            new WaitCallback(CalculateThirdTerm));

        // Wait for all of the terms to be calculated.
        WaitHandle.WaitAll(autoEvents);

        // Reset the wait handle for the next calculation.
        manualEvent.Reset();

        return firstTerm + secondTerm + thirdTerm;
    }
}
Visual C++
using namespace System;
using namespace System::Threading;
ref class Calculate
{
private:
   double baseNumber;
   double firstTerm;
   double secondTerm;
   double thirdTerm;
   array<AutoResetEvent^>^autoEvents;
   ManualResetEvent^ manualEvent;

   // Generate random numbers to simulate the actual calculations.
   Random^ randomGenerator;

public:
   Calculate()
   {
      autoEvents = gcnew array<AutoResetEvent^>(3);
      autoEvents[ 0 ] = gcnew AutoResetEvent( false );
      autoEvents[ 1 ] = gcnew AutoResetEvent( false );
      autoEvents[ 2 ] = gcnew AutoResetEvent( false );
      manualEvent = gcnew ManualResetEvent( false );
   }


private:
   void CalculateBase( Object^ /*stateInfo*/ )
   {
      baseNumber = randomGenerator->NextDouble();

      // Signal that baseNumber is ready.
      manualEvent->Set();
   }


   // The following CalculateX methods all perform the same
   // series of steps as commented in CalculateFirstTerm.
   void CalculateFirstTerm( Object^ /*stateInfo*/ )
   {

      // Perform a precalculation.
      double preCalc = randomGenerator->NextDouble();

      // Wait for baseNumber to be calculated.
      manualEvent->WaitOne();

      // Calculate the first term from preCalc and baseNumber.
      firstTerm = preCalc * baseNumber * randomGenerator->NextDouble();

      // Signal that the calculation is finished.
      autoEvents[ 0 ]->Set();
   }

   void CalculateSecondTerm( Object^ /*stateInfo*/ )
   {
      double preCalc = randomGenerator->NextDouble();
      manualEvent->WaitOne();
      secondTerm = preCalc * baseNumber * randomGenerator->NextDouble();
      autoEvents[ 1 ]->Set();
   }

   void CalculateThirdTerm( Object^ /*stateInfo*/ )
   {
      double preCalc = randomGenerator->NextDouble();
      manualEvent->WaitOne();
      thirdTerm = preCalc * baseNumber * randomGenerator->NextDouble();
      autoEvents[ 2 ]->Set();
   }


public:
   double Result( int seed )
   {
      randomGenerator = gcnew Random( seed );

      // Simultaneously calculate the terms.
      ThreadPool::QueueUserWorkItem( gcnew WaitCallback( this, &Calculate::CalculateBase ) );
      ThreadPool::QueueUserWorkItem( gcnew WaitCallback( this, &Calculate::CalculateFirstTerm ) );
      ThreadPool::QueueUserWorkItem( gcnew WaitCallback( this, &Calculate::CalculateSecondTerm ) );
      ThreadPool::QueueUserWorkItem( gcnew WaitCallback( this, &Calculate::CalculateThirdTerm ) );

      // Wait for all of the terms to be calculated.
      WaitHandle::WaitAll( autoEvents );

      // Reset the wait handle for the next calculation.
      manualEvent->Reset();
      return firstTerm + secondTerm + thirdTerm;
   }

};

int main()
{
   Calculate^ calc = gcnew Calculate;
   Console::WriteLine( "Result = {0}.", calc->Result( 234 ).ToString() );
   Console::WriteLine( "Result = {0}.", calc->Result( 55 ).ToString() );
}

J#
import System.*;
import System.Threading.*;

class CalculateTest
{
    public static void main(String[] args)
    {
        Calculate calc = new Calculate();
        Console.WriteLine("Result = {0}.", String.valueOf(calc.Result(234)));
        Console.WriteLine("Result = {0}.", String.valueOf(calc.Result(55)));
    } //main
} //CalculateTest

class Calculate
{
    private double baseNumber, firstTerm, secondTerm, thirdTerm;
    private AutoResetEvent autoEvents[];
    private ManualResetEvent manualEvent;

    // Generate random numbers to simulate the actual calculations.
    private Random randomGenerator;

    public Calculate()
    {
        autoEvents = new AutoResetEvent[] { new AutoResetEvent(false), 
            new AutoResetEvent(false), new AutoResetEvent(false) };
        manualEvent = new ManualResetEvent(false);
    } //Calculate

    void CalculateBase(Object stateInfo)
    {
        baseNumber = randomGenerator.NextDouble();

        // Signal that baseNumber is ready.
        manualEvent.Set();
    } //CalculateBase

    // The following CalculateX methods all perform the same
    // series of steps as commented in CalculateFirstTerm.
    void CalculateFirstTerm(Object stateInfo)
    {
        // Perform a precalculation.
        double preCalc = randomGenerator.NextDouble();

        // Wait for baseNumber to be calculated.
        manualEvent.WaitOne();

        // Calculate the first term from preCalc and baseNumber.
        firstTerm = preCalc * baseNumber * randomGenerator.NextDouble();

        // Signal that the calculation is finished.
        autoEvents[0].Set();
    } //CalculateFirstTerm

    void CalculateSecondTerm(Object stateInfo)
    {
        double preCalc = randomGenerator.NextDouble();

        manualEvent.WaitOne();
        secondTerm = preCalc * baseNumber * randomGenerator.NextDouble();
        autoEvents[1].Set();
    } //CalculateSecondTerm

    void CalculateThirdTerm(Object stateInfo)
    {
        double preCalc = randomGenerator.NextDouble();

        manualEvent.WaitOne();
        thirdTerm = preCalc * baseNumber * randomGenerator.NextDouble();
        autoEvents[2].Set();
    } //CalculateThirdTerm

    public double Result(int seed)
    {
        randomGenerator = new Random(seed);

        // Simultaneously calculate the terms.
        ThreadPool.QueueUserWorkItem(new WaitCallback(CalculateBase));
        ThreadPool.QueueUserWorkItem(new WaitCallback(CalculateFirstTerm));
        ThreadPool.QueueUserWorkItem(new WaitCallback(CalculateSecondTerm));
        ThreadPool.QueueUserWorkItem(new WaitCallback(CalculateThirdTerm));

        // Wait for all of the terms to be calculated.
        WaitHandle.WaitAll(autoEvents);

        // Reset the wait handle for the next calculation.
        manualEvent.Reset();
        return firstTerm + secondTerm + thirdTerm;
    } //Result
} //Calculate
繼承階層架構

System..::.Object
  System..::.MarshalByRefObject
    System.Threading..::.WaitHandle
      System.Threading..::.EventWaitHandle
        System.Threading..::.ManualResetEvent
執行緒安全

此類別具備執行緒安全。

平台

Windows Vista, Windows XP SP2, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP Starter Edition, Windows Server 2003, Windows Server 2000 SP4, Windows Millennium Edition, Windows 98, Windows CE, Windows Mobile for Smartphone, Windows Mobile for Pocket PC, Xbox 360

.NET Framework 和 .NET Compact Framework 並不支援各種平台的所有版本。如需支援平台版本的相關資訊,請參閱 .NET Framework 系統需求

版本資訊

.NET Framework

支援版本:3.5、3.0、2.0、1.1、1.0

.NET Compact Framework

支援版本:3.5、2.0、1.0

XNA Framework

支援版本:2.0、1.0
請參閱

參考

其他資源

標記 :


Page view tracker