다음을 통해 공유


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

설명

대기 시간이 매우 짧을 것으로 예상되는 경우와 이벤트가 프로세스 경계를 넘지 않는 경우보다 ManualResetEvent 성능 향상을 위해 이 클래스를 사용할 수 있습니다. ManualResetEventSlim에서는 이벤트에 신호가 전달되기를 기다리는 짧은 시간 동안 고속 회전을 사용합니다. 대기 시간이 짧은 경우 대기 핸들을 사용하여 기다리는 것보다 회전하는 것이 비용이 적게 들 수 있습니다. 그러나 이벤트가 특정 기간 내에 신호를 받지 않는 경우 일반적인 이벤트 핸들 대기에 ManualResetEventSlim을 사용합니다.

참고

.NET Core 및 .NET 5 이상에서는 플랫폼 및 프로세서에 따라 기본 스핀 대기 기간이 10초 단위로 짧습니다. 대기 시간이 그보다 훨씬 길어질 것으로 예상되는 경우에도 이 클래스를 ManualResetEvent 대신 사용할 수 있습니다(아마도 스핀 대기 시간이 적거나 전혀 없는 것으로 구성됨). 그러나 성능 이점은 미미할 수 있습니다.

생성자

ManualResetEventSlim()

신호 없음을 초기 상태로 사용하여 ManualResetEventSlim 클래스의 새 인스턴스를 초기화합니다.

ManualResetEventSlim(Boolean)

초기 상태를 신호 받음으로 설정할지 여부를 나타내는 부울 값을 사용하여 ManualResetEventSlim 클래스의 새 인스턴스를 초기화합니다.

ManualResetEventSlim(Boolean, Int32)

초기 상태를 신호 받음으로 설정할지 여부를 나타내는 부울 값과 지정된 회전 수를 사용하여 ManualResetEventSlim 클래스의 새 인스턴스를 초기화합니다.

속성

IsSet

이벤트가 설정되었는지를 가져옵니다.

SpinCount

커널 기반의 대기 작업으로 대체하기 전에 수행되는 회전 대기 수를 가져옵니다.

WaitHandle

WaitHandle의 내부 ManualResetEventSlim 개체를 가져옵니다.

메서드

Dispose()

ManualResetEventSlim 클래스의 현재 인스턴스에서 사용하는 모든 리소스를 해제합니다.

Dispose(Boolean)

ManualResetEventSlim에서 사용하는 관리되지 않는 리소스를 해제하고, 관리되는 리소스를 선택적으로 해제할 수 있습니다.

Equals(Object)

지정된 개체가 현재 개체와 같은지 확인합니다.

(다음에서 상속됨 Object)
GetHashCode()

기본 해시 함수로 작동합니다.

(다음에서 상속됨 Object)
GetType()

현재 인스턴스의 Type을 가져옵니다.

(다음에서 상속됨 Object)
MemberwiseClone()

현재 Object의 단순 복사본을 만듭니다.

(다음에서 상속됨 Object)
Reset()

스레드가 차단되도록 이벤트 상태를 신호 없음으로 설정합니다.

Set()

이벤트에서 대기 중인 하나 이상의 스레드가 계속 진행되도록 이벤트 상태를 신호 받음으로 설정합니다.

ToString()

현재 개체를 나타내는 문자열을 반환합니다.

(다음에서 상속됨 Object)
Wait()

현재 ManualResetEventSlim이 설정될 때까지 현재 스레드를 차단합니다.

Wait(CancellationToken)

ManualResetEventSlim을 확인하면서 현재 CancellationToken이 신호를 받을 때까지 현재 스레드를 차단합니다.

Wait(Int32)

부호 있는 32비트 정수로 시간 간격을 측정하여 현재 ManualResetEventSlim이 설정될 때까지 현재 스레드를 차단합니다.

Wait(Int32, CancellationToken)

ManualResetEventSlim을 확인하면서 부호 있는 32비트 정수로 시간 간격을 측정하여 현재 CancellationToken이 설정될 때까지 현재 스레드를 차단합니다.

Wait(TimeSpan)

ManualResetEventSlim으로 시간 간격을 측정하여 현재 TimeSpan이 설정될 때까지 현재 스레드를 차단합니다.

Wait(TimeSpan, CancellationToken)

ManualResetEventSlim을 확인하면서 TimeSpan으로 시간 간격을 측정하여 현재 CancellationToken이 설정될 때까지 현재 스레드를 차단합니다.

적용 대상

스레드 보안

모든 공용 및 보호된 멤버 ManualResetEventSlim 는 스레드로부터 안전하며 여러 스레드에서 동시에 사용할 수 있습니다. 단, Dispose는 다른 모든 작업이 ManualResetEventSlim 완료된 경우에만 사용해야 하며 다시 설정은 다른 스레드가 이벤트에 액세스하지 않는 경우에만 사용해야 합니다.

추가 정보