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+ 中,預設的旋轉等待時間很短:約數十微秒,視平台與處理器而定。 如果你預期等待時間會比這更長,你仍然可以使用這個類別( ManualResetEvent 或許可以設定較少或不等待旋轉等待)。 不過,效能上的提升可能只是微乎其微。
建構函式
| 名稱 | Description |
|---|---|
| ManualResetEventSlim() |
初始化類別的新實例 ManualResetEventSlim ,初始狀態為 non signaled。 |
| ManualResetEventSlim(Boolean, Int32) |
初始化一個新的類別實例 ManualResetEventSlim ,並以布林值表示是否將初始狀態設為訊號狀態並設定指定的自旋計數。 |
| ManualResetEventSlim(Boolean) |
初始化一個新的類別實例 ManualResetEventSlim ,並以布林值表示是否將初始狀態設為 signaled。 |
屬性
| 名稱 | Description |
|---|---|
| IsSet |
判斷事件是否被設定。 |
| SpinCount |
取得在回退到基於核心的等待操作前會發生的旋轉等待次數。 |
| WaitHandle |
取得此底WaitHandle層ManualResetEventSlim物件。 |
方法
| 名稱 | 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,僅在沒有其他執行緒存取事件時使用。