Semaphore の WaitOne(Int32) メソッドのMSDN ドキュメントでは、ゼロの値を指定すると、スロットが開くのを待たずにメソッドがすぐに戻ると書かれています。SemaphoreSlimバージョンのドキュメントには、同じことは書かれていません。SemaphoreSlim はこの動作を共有しますか?
これを自分でテストするタイミングを保証する方法がわかりません。
Semaphore の WaitOne(Int32) メソッドのMSDN ドキュメントでは、ゼロの値を指定すると、スロットが開くのを待たずにメソッドがすぐに戻ると書かれています。SemaphoreSlimバージョンのドキュメントには、同じことは書かれていません。SemaphoreSlim はこの動作を共有しますか?
これを自分でテストするタイミングを保証する方法がわかりません。
タイムアウト 0 を渡した場合は、SemaphoreSlim.Wait
戻る前に常にスロットの取得を試みます。数回の操作とSpinOnce
.
編集: 明確化:これはおそらく と同じ見かけの動作Semaphore
です。のドキュメントからSemaphore
:
待機ハンドルの状態をテストし、すぐに戻ります
ただしSemaphoreSlim
、Wait メソッドを使用すると、 を使用してスロットを開く機会が与えられますSpinOnce
。
(編集終了)
また、SemaphoreSlim
スロットの取得を試みる前に、いくつかの操作を実行します。これらの 1 つは であるMonitor.Enter
ため、その時点で待機中または解放中の他のスレッドを待機できます。したがって、必ずしもすぐに戻るとは限りません。
私が知る限り、イベントの順序は次のとおりです。
CancellationTokenRegistration
SpinWait.SpinOnce
スキップします) (編集: ステップ 2 がステップ 5 と同じテストを実行することを強調するために、これを太字にしました。最終テストと終了)NextSpinWillYield
true
Monitor.Enter
(Release と WaitAsync が入るのと同じロック)false
AvailableWaitHandle
使用されていて、使用可能なスロット カウントが再び 0 になった場合は、の下の waitHandle をリセットします。CancellationTokenRegistration
true
(ゼロ以外のタイムアウトを使用している他のスレッドは、 を呼び出してカウンターを保護するために使用されるロックを断続的に解放および取得することに注意してください。そのMonitor.Wait
ため、タイムアウト 0 で永遠に待機することはなく、非常に短い時間だけです。)
したがって、スロットに開く機会を与えるため、SemaphoreSlim
まったく同じ 0 タイムアウト動作を と共有しているようには見えません。(セマフォのインスタンス化を変更するだけで古いコードをアップグレードするときにコードがコンパイルされないようにするためのand -Sempahore
がある理由かもしれません。したがって、動作をチェックする必要があります)。Semaphore.WaitOne
SemaphoreSlim.Wait
記事Semaphore vs. SemaphoreSlimでは、この動作は強調されておらず、2 つの基本的な違いのみが強調されています。
サイドノート:
興味深いことに、その参照には次のようにも記載されています
[SemaphoreSlim] はサポートしていません... 同期のための待機ハンドルの使用
それでも、 SemaphoreSlim.AvailableWaitHandleのドキュメントには別の言い方があります。