3

WindowsAzureで実行されているアプリケーション用のグローバルエラーハンドラー/ロガーを作成しています。アプリケーションでエラーが発生すると、アトミックに発生する必要のあるいくつかの操作が実行されます。前のエラーが完了するまでエラーがログに記録されないようにする必要があります。その間、必要に応じてログの読み取りを実行したいと思います。

私の最初の考えは、モニター/ロックを使用して、エラー書き込みのみをロックすることでした。そうすれば、読み取りがまったく禁止されません。ReaderWriterLockSlimの方が適切かどうか疑問に思いました。あるアプローチと他のアプローチの価値を本当に理解しているとは言えません。

ReaderWriterLockSlimを作成し、次のようなことを行う必要があります(読み取りはEnterReadLockでラップされます)...

public static void LogError(Exception exception)
{
    _lock.EnterWriteLock();

    ...

    _lock.ExitWriteLock();
}

または、書き込みセクションのみをロックして、次のようなことを行うだけですか。

public static void LogError(Exception exception)
{
     lock (someStaticLock)
     {
        ...
     }
}

任意の考え/アドバイスをいただければ幸いです。

4

3 に答える 3

4

OK、それはリソースの競合がどのように予想されるかに完全に依存します。以下は、ロックしているものとロックの量に基づいて行う簡単な決定です。

ReaderWriterLockSlim はスピンロックを使用して実装されるため、長いロック リソース (この場合はテキストの書き込み) がある場合、待機中のスレッドによるスピンのためにパフォーマンスが低下します。とはいえ、次のような状況で非常に便利なツールです。

  • 多数のロックがあり、それぞれがよりきめ細かい (非常に小さなコードのロック) 場合は、ReaderWriterLockSlim または (スピンロック) を使用します。
  • 予想されるスレッド数または競合の数が多い場合 スピンロックは、ロックがきめの細かいものであれば理にかなっています。

ロックまたはモニターは、競合が粗粒度で、競合またはロックの数が少ないことがわかっている場合に最適です。

ReaderWriterLockSlim は、ReaderWriterLock より少なくとも 3 ~ 5 倍高速です。

于 2011-03-04T01:17:30.107 に答える
4

Queue を使用して、発生した例外を保存し、バックグラウンド ワーカー スレッドに吐き出してみませんか? 次に、両側でエンキュー/デキューをロックするだけです。衝突のウィンドウはかなり小さく保つことができ、順序が維持されるため、ログ データの実際の書き込みが遅れても問題ありません。必要に応じて、アイテムがエンキューされたときのタイムスタンプを含むコレクションに例外をラップして、適切にタイムスタンプを付けることができます。

于 2011-03-04T02:33:36.983 に答える
0

アトミック操作の進行中に読めるので、ロックなしで読むべきではないと思います。ReaderWriterLock は、書き込み処理中にリーダーが入力できないことを保証するため、より優れているようです。

于 2011-03-04T01:04:40.567 に答える