ManualResetEventSlim 類別

定義

表示必須手動重設訊號的線程同步處理事件。 此類別是 的輕量級替代方案 ManualResetEvent

public ref class ManualResetEventSlim : IDisposable
public class ManualResetEventSlim : IDisposable
[System.Runtime.InteropServices.ComVisible(false)]
public class ManualResetEventSlim : IDisposable
type ManualResetEventSlim = class
    interface IDisposable
[<System.Runtime.InteropServices.ComVisible(false)>]
type ManualResetEventSlim = class
    interface IDisposable
Public Class ManualResetEventSlim
Implements IDisposable
繼承
ManualResetEventSlim
屬性
實作

範例

以下範例展示了如何使用 ManualResetEventSlim

using System;
using System.Threading;
using System.Threading.Tasks;
class MRESDemo
{

    static void Main()
    {
        MRES_SetWaitReset();
        MRES_SpinCountWaitHandle();
    }
    // Demonstrates:
    //      ManualResetEventSlim construction
    //      ManualResetEventSlim.Wait()
    //      ManualResetEventSlim.Set()
    //      ManualResetEventSlim.Reset()
    //      ManualResetEventSlim.IsSet
    static void MRES_SetWaitReset()
    {
        ManualResetEventSlim mres1 = new ManualResetEventSlim(false); // initialize as unsignaled
        ManualResetEventSlim mres2 = new ManualResetEventSlim(false); // initialize as unsignaled
        ManualResetEventSlim mres3 = new ManualResetEventSlim(true);  // initialize as signaled

        // Start an asynchronous Task that manipulates mres3 and mres2
        var observer = Task.Factory.StartNew(() =>
        {
            mres1.Wait();
            Console.WriteLine("observer sees signaled mres1!");
            Console.WriteLine("observer resetting mres3...");
            mres3.Reset(); // should switch to unsignaled
            Console.WriteLine("observer signalling mres2");
            mres2.Set();
        });

        Console.WriteLine("main thread: mres3.IsSet = {0} (should be true)", mres3.IsSet);
        Console.WriteLine("main thread signalling mres1");
        mres1.Set(); // This will "kick off" the observer Task
        mres2.Wait(); // This won't return until observer Task has finished resetting mres3
        Console.WriteLine("main thread sees signaled mres2!");
        Console.WriteLine("main thread: mres3.IsSet = {0} (should be false)", mres3.IsSet);

        // It's good form to Dispose() a ManualResetEventSlim when you're done with it
        observer.Wait(); // make sure that this has fully completed
        mres1.Dispose();
        mres2.Dispose();
        mres3.Dispose();
    }

    // Demonstrates:
    //      ManualResetEventSlim construction w/ SpinCount
    //      ManualResetEventSlim.WaitHandle
    static void MRES_SpinCountWaitHandle()
    {
        // Construct a ManualResetEventSlim with a SpinCount of 1000
        // Higher spincount => longer time the MRES will spin-wait before taking lock
        ManualResetEventSlim mres1 = new ManualResetEventSlim(false, 1000);
        ManualResetEventSlim mres2 = new ManualResetEventSlim(false, 1000);

        Task bgTask = Task.Factory.StartNew(() =>
        {
            // Just wait a little
            Thread.Sleep(100);

            // Now signal both MRESes
            Console.WriteLine("Task signalling both MRESes");
            mres1.Set();
            mres2.Set();
        });

        // A common use of MRES.WaitHandle is to use MRES as a participant in 
        // WaitHandle.WaitAll/WaitAny.  Note that accessing MRES.WaitHandle will
        // result in the unconditional inflation of the underlying ManualResetEvent.
        WaitHandle.WaitAll(new WaitHandle[] { mres1.WaitHandle, mres2.WaitHandle });
        Console.WriteLine("WaitHandle.WaitAll(mres1.WaitHandle, mres2.WaitHandle) completed.");

        // Clean up
        bgTask.Wait();
        mres1.Dispose();
        mres2.Dispose();
    }
}
Imports System.Threading
Imports System.Threading.Tasks

Module MRESDemo

    Sub Main()

    End Sub
    ' Demonstrates:
    ' ManualResetEventSlim construction
    ' ManualResetEventSlim.Wait()
    ' ManualResetEventSlim.Set()
    ' ManualResetEventSlim.Reset()
    ' ManualResetEventSlim.IsSet
    Private Sub MRES_SetWaitReset()
        ' initialize as unsignaled
        Dim mres1 As New ManualResetEventSlim(False)
        ' initialize as unsignaled
        Dim mres2 As New ManualResetEventSlim(False)
        ' initialize as signaled
        Dim mres3 As New ManualResetEventSlim(True)

        ' Start an asynchronous Task that manipulates mres3 and mres2
        Dim observer = Task.Factory.StartNew(
            Sub()
                mres1.Wait()
                Console.WriteLine("observer sees signaled mres1!")
                Console.WriteLine("observer resetting mres3...")
                mres3.Reset()
                ' should switch to unsignaled
                Console.WriteLine("observer signalling mres2")
                mres2.[Set]()
            End Sub)

        Console.WriteLine("main thread: mres3.IsSet = {0} (should be true)", mres3.IsSet)
        Console.WriteLine("main thread signalling mres1")
        mres1.[Set]()
        ' This will "kick off" the observer Task
        mres2.Wait()
        ' This won't return until observer Task has finished resetting mres3
        Console.WriteLine("main thread sees signaled mres2!")
        Console.WriteLine("main thread: mres3.IsSet = {0} (should be false)", mres3.IsSet)

        ' make sure that observer has fully completed
        observer.Wait()
        ' It's good form to Dispose() a ManualResetEventSlim when you're done with it
        mres1.Dispose()
        mres2.Dispose()
        mres3.Dispose()
    End Sub

    ' Demonstrates:
    ' ManualResetEventSlim construction w/ SpinCount
    ' ManualResetEventSlim.WaitHandle
    Private Sub MRES_SpinCountWaitHandle()
        ' Construct a ManualResetEventSlim with a SpinCount of 1000
        ' Higher spincount => longer time the MRES will spin-wait before taking lock
        Dim mres1 As New ManualResetEventSlim(False, 1000)
        Dim mres2 As New ManualResetEventSlim(False, 1000)

        Dim bgTask As Task = Task.Factory.StartNew(
            Sub()
                ' Just wait a little
                Thread.Sleep(100)

                ' Now signal both MRESes
                Console.WriteLine("Task signalling both MRESes")
                mres1.[Set]()
                mres2.[Set]()
            End Sub)

        ' A common use of MRES.WaitHandle is to use MRES as a participant in 
        ' WaitHandle.WaitAll/WaitAny. Note that accessing MRES.WaitHandle will
        ' result in the unconditional inflation of the underlying ManualResetEvent.
        WaitHandle.WaitAll(New WaitHandle() {mres1.WaitHandle, mres2.WaitHandle})
        Console.WriteLine("WaitHandle.WaitAll(mres1.WaitHandle, mres2.WaitHandle) completed.")

        ' Wait for bgTask to complete and clean up
        bgTask.Wait()
        mres1.Dispose()
        mres2.Dispose()
    End Sub
End Module

備註

你可以利用這個類別,在等待時間預期非常短或事件未跨越程序邊界時,表現更好 ManualResetEventManualResetEventSlim 在等待事件被發出訊號時,會短暫使用忙碌旋轉。 當等待時間短時,旋轉的成本通常遠低於使用等待把手等待。 然而,如果事件在一定時間內未被發出訊號,則 ManualResetEventSlim 會採用一般的事件處理等待。

Note

在 .NET Core 與 .NET 5+ 中,預設的旋轉等待時間很短:約數十微秒,視平台與處理器而定。 如果你預期等待時間會比這更長,你仍然可以使用這個類別( ManualResetEvent 或許可以設定較少或不等待旋轉等待)。 不過,效能上的提升可能只是微乎其微。

建構函式

名稱 Description
ManualResetEventSlim()

初始化類別的新實例 ManualResetEventSlim ,初始狀態為 non signaled。

ManualResetEventSlim(Boolean, Int32)

初始化一個新的類別實例 ManualResetEventSlim ,並以布林值表示是否將初始狀態設為訊號狀態並設定指定的自旋計數。

ManualResetEventSlim(Boolean)

初始化一個新的類別實例 ManualResetEventSlim ,並以布林值表示是否將初始狀態設為 signaled。

屬性

名稱 Description
IsSet

判斷事件是否被設定。

SpinCount

取得在回退到基於核心的等待操作前會發生的旋轉等待次數。

WaitHandle

取得此底WaitHandleManualResetEventSlim物件。

方法

名稱 Description
Dispose()

釋放目前類別實例 ManualResetEventSlim 所使用的所有資源。

Dispose(Boolean)

釋放 所使用的 ManualResetEventSlim未管理資源,並可選擇性地釋放受管理資源。

Equals(Object)

判斷指定的物件是否等於目前的物件。

(繼承來源 Object)
GetHashCode()

做為預設哈希函式。

(繼承來源 Object)
GetType()

取得目前實例的 Type

(繼承來源 Object)
MemberwiseClone()

建立目前 Object的淺層複本。

(繼承來源 Object)
Reset()

將事件的狀態設定為非ignaled,這會導致線程封鎖。

Set()

將事件狀態設為已訊號,允許一個或多個等待事件的執行緒繼續進行。

ToString()

傳回表示目前 物件的字串。

(繼承來源 Object)
Wait()

阻塞目前執行緒,直到設定好當前 ManualResetEventSlim 執行緒。

Wait(CancellationToken)

在觀察 時ManualResetEventSlim,阻擋當前執行緒直到電流CancellationToken接收到訊號。

Wait(Int32, CancellationToken)

在設定當前執行緒之前,會阻塞當前執行緒ManualResetEventSlim,使用一個 32 位元帶符號的整數來測量時間區間,同時觀察 。CancellationToken

Wait(Int32)

在設定當前執行緒之前,會封鎖當前執行緒 ManualResetEventSlim ,並使用一個 32 位元有符號整數來測量時間區間。

Wait(TimeSpan, CancellationToken)

在設定電流前阻塞當前執行緒ManualResetEventSlim,利用 a TimeSpan 測量時間區間,同時觀察 。CancellationToken

Wait(TimeSpan)

阻塞目前執行緒直到電流 ManualResetEventSlim 設定完成,並使用 a TimeSpan 來衡量時間區間。

適用於

執行緒安全性

所有公開且受保護的成員 ManualResetEventSlim 皆為執行緒安全,且可同時從多個執行緒使用,唯獨 Dispose 必須在所有其他操作 ManualResetEventSlim 完成後使用,以及 Reset,僅在沒有其他執行緒存取事件時使用。

另請參閱