ManualResetEventSlim クラス
定義
重要
一部の情報は、リリース前に大きく変更される可能性があるプレリリースされた製品に関するものです。 Microsoft は、ここに記載されている情報について、明示または黙示を問わず、一切保証しません。
通知されたら手動でリセットする必要があるスレッド同期イベントを表します。 このクラスは、 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 は通常のイベント ハンドル待機に頼ります。
Note
.NET Core と .NET 5 以降では、既定のスピン待機期間は短く、プラットフォームとプロセッサに応じて 10 マイクロ秒の順序です。 待機時間がそれより長くなることが予想される場合でも、 ManualResetEvent ではなくこのクラスを使用できます (スピン待機が少ない、またはまったく構成されていない可能性があります)。 ただし、パフォーマンス上の利点は限界に過ぎない可能性があります。
コンストラクター
| 名前 | 説明 |
|---|---|
| ManualResetEventSlim() |
初期状態が非署名の ManualResetEventSlim クラスの新しいインスタンスを初期化します。 |
| ManualResetEventSlim(Boolean, Int32) |
初期状態を signaled に設定するかどうかを示すブール値と、指定したスピンカウントを使用して、 ManualResetEventSlim クラスの新しいインスタンスを初期化します。 |
| ManualResetEventSlim(Boolean) |
初期状態を signaled に設定するかどうかを示すブール値を使用して、 ManualResetEventSlim クラスの新しいインスタンスを初期化します。 |
プロパティ
| 名前 | 説明 |
|---|---|
| IsSet |
イベントが設定されているかどうかを取得します。 |
| SpinCount |
カーネル ベースの待機操作にフォールバックする前に発生するスピン待機の数を取得します。 |
| WaitHandle |
このWaitHandleの基になるManualResetEventSlim オブジェクトを取得します。 |
メソッド
| 名前 | 説明 |
|---|---|
| Dispose() |
ManualResetEventSlim クラスの現在のインスタンスで使用されているすべてのリソースを解放します。 |
| Dispose(Boolean) |
ManualResetEventSlimによって使用されるアンマネージ リソースを解放し、必要に応じてマネージド リソースを解放します。 |
| Equals(Object) |
指定したオブジェクトが現在のオブジェクトと等しいかどうかを判断します。 (継承元 Object) |
| GetHashCode() |
既定のハッシュ関数として機能します。 (継承元 Object) |
| GetType() |
現在のインスタンスの Type を取得します。 (継承元 Object) |
| MemberwiseClone() |
現在の Objectの簡易コピーを作成します。 (継承元 Object) |
| Reset() |
イベントの状態を非署名に設定します。これにより、スレッドがブロックされます。 |
| Set() |
イベントの状態を signaled に設定します。これにより、イベントを待機している 1 つ以上のスレッドが続行できるようになります。 |
| ToString() |
現在のオブジェクトを表す文字列を返します。 (継承元 Object) |
| Wait() |
現在の ManualResetEventSlim が設定されるまで、現在のスレッドをブロックします。 |
| Wait(CancellationToken) |
ManualResetEventSlimを観察しながら、現在のCancellationTokenがシグナルを受信するまで、現在のスレッドをブロックします。 |
| Wait(Int32, CancellationToken) |
ManualResetEventSlimを観察しながら、32 ビット符号付き整数を使用して時間間隔を測定し、現在のCancellationTokenが設定されるまで、現在のスレッドをブロックします。 |
| Wait(Int32) |
32 ビット符号付き整数を使用して時間間隔を測定し、現在の ManualResetEventSlim が設定されるまで、現在のスレッドをブロックします。 |
| Wait(TimeSpan, CancellationToken) |
ManualResetEventSlimを観察しながら、TimeSpanを使用して時間間隔を測定し、現在のCancellationTokenが設定されるまで、現在のスレッドをブロックします。 |
| Wait(TimeSpan) |
ManualResetEventSlimを使用して時間間隔を測定し、現在のTimeSpanが設定されるまで、現在のスレッドをブロックします。 |
適用対象
スレッド セーフ
ManualResetEventSlimのすべてのパブリック メンバーと保護されたメンバーはスレッド セーフであり、複数のスレッドから同時に使用できます。ただし、Dispose は、ManualResetEventSlimに対する他のすべての操作が完了した場合にのみ使用する必要があります。Reset は、他のスレッドがイベントにアクセスしていない場合にのみ使用する必要があります。