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 就會訴諸於一般的事件控制代碼等候。
注意
在 .NET Core 和 .NET 5+中,預設的微調等候持續時間很短:視平臺和處理器而定,依 10 秒的微秒順序而定。 如果您預期等候時間比該時間長很多,您仍然可以使用此類別,而不 ManualResetEvent 要使用 (設定較少或沒有微調等候) 。 不過,效能優勢可能只是臨界值。
建構函式
ManualResetEventSlim() |
使用未收到訊號的初始狀態來初始化 ManualResetEventSlim 類別的新執行個體。 |
ManualResetEventSlim(Boolean) |
使用布林值 (Boolean) 來初始化 ManualResetEventSlim 類別的新執行個體,指出初始狀態是否設定為信號狀態。 |
ManualResetEventSlim(Boolean, Int32) |
使用指出是否要將初始狀態設為已收到訊號及指定微調計數的布林值,來初始化 ManualResetEventSlim 類別的新執行個體。 |
屬性
IsSet |
取得值,表示事件是否已設定。 |
SpinCount |
取得在回到以核心為基礎的等候作業之前進行微調等候的次數。 |
WaitHandle |
取得這個 WaitHandle 的基礎 ManualResetEventSlim 物件。 |
方法
Dispose() |
釋放 ManualResetEventSlim 類別目前的執行個體所使用的全部資源。 |
Dispose(Boolean) |
釋放 ManualResetEventSlim 所使用的 Unmanaged 資源,並選擇性釋放 Managed 資源。 |
Equals(Object) |
判斷指定的物件是否等於目前的物件。 (繼承來源 Object) |
GetHashCode() |
做為預設雜湊函式。 (繼承來源 Object) |
GetType() |
取得目前執行個體的 Type。 (繼承來源 Object) |
MemberwiseClone() |
建立目前 Object 的淺層複製。 (繼承來源 Object) |
Reset() |
將事件的狀態設定為未收到信號,會造成執行緒封鎖。 |
Set() |
將事件的狀態設定為已收到訊號,讓正在等候該事件的一或多個執行緒繼續執行。 |
ToString() |
傳回代表目前物件的字串。 (繼承來源 Object) |
Wait() |
封鎖目前的執行緒,直到設定了目前的 ManualResetEventSlim 為止。 |
Wait(CancellationToken) |
封鎖目前的執行緒,直到目前的 ManualResetEventSlim 收到訊號為止,同時觀察 CancellationToken。 |
Wait(Int32) |
封鎖目前的執行緒,直到設定了目前的 ManualResetEventSlim 為止 (使用 32 位元帶正負號的整數以測量時間間隔)。 |
Wait(Int32, CancellationToken) |
封鎖目前的執行緒,直到設定了目前的 ManualResetEventSlim 為止,並使用 32 位元帶正負號的整數以量測時間間隔,同時觀察 CancellationToken。 |
Wait(TimeSpan) |
封鎖目前的執行緒,直到設定了目前的 ManualResetEventSlim 為止,並使用 TimeSpan 以量測時間間隔。 |
Wait(TimeSpan, CancellationToken) |
封鎖目前的執行緒,直到設定了目前的 ManualResetEventSlim 為止,並使用 TimeSpan 以量測時間間隔,同時觀察 CancellationToken。 |
適用於
執行緒安全性
的所有公用和受保護的成員 ManualResetEventSlim 都是安全線程,而且可以同時從多個執行緒使用,但 Dispose 除外,這只能用於 上所有其他作業 ManualResetEventSlim 完成時使用,而且只有在沒有其他執行緒存取事件時才應該使用。