問題タブ [rategate]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
2 に答える
6933 参照

c# - アプリの障害を危険にさらすことなく SemaphoreSlim.Release() を呼び出す方法は?

SemaphoreSlim.NET 4.0 の新しいクラスを使用して、無限に実行できるペースの速いループをレート制限しようとしています。これを単体テストしたところ、ループが十分にタイトで並列度が十分に高い場合、 を呼び出すと、最初にプロパティをチェックしてセマフォ インスタンス自体をロックしてもSemaphoreSlim、キャッチ不能な例外がスローされることがわかりました。チェックカウント/リリースシーケンス全体。Release().Count

この例外により、アプリが停止します。私が知る限り、それを捕まえることはありません。

より深く掘り下げると、呼び出し中に内部的にSemaphoreSlim独自のプロパティにアクセスしようとしていることがわかりました。インスタンス自体にアクセスするのではなく、例外がスローされます。(これを発見するには、Debug->Exceptions->Common Language Runtime Exceptions->Thrown all checked in Visual Studio でデバッグする必要がありました。実行時にキャッチすることはできません。詳細については、キャッチできない例外を参照してください。).AvailableWaitHandleRelease()SemaphoreSlim

私の質問は、そのような場合にアプリがすぐに終了する危険を冒さずに、このクラスを使用する防弾方法を知っている人はいますか?

注: セマフォ インスタンスは、RateGate インスタンスにラップされています。コードは、記事「Better Rate Limiting in .NET 」に記載されています。

更新: 再現する完全なコンソール アプリ コードを追加しています。どちらの回答も解決に貢献しました。説明については、以下を参照してください。

そのため、@dtb のソリューションを使用すると、スレッド "a" が_isDisposedチェックを通過しても、スレッド "a" がヒットする前にスレッド "b" がセマフォを破棄する可能性がありましたRelease()。ExitTimerCallback メソッドと Dispose メソッドの両方で _semaphore インスタンスの周りにロックを追加することがわかりました。@Peter Ritchieの提案により、セマフォを破棄する前に、タイマーをさらにキャンセルして破棄するようになりました。これら 2 つのことの組み合わせにより、プログラムは完了し、RateGate を例外なく適切に破棄できます。

その入力がなければこれを取得できなかったので、自分で答えたくありません。しかし、完全な回答が得られると StackOverflow はより便利になるため、上記のコンソール アプリで問題なく生き残ったパッチまたは疑似パッチを最初に投稿した人を受け入れます。