2017-09-22 11 views
2

アプリケーションでC#lock()を使用して、同じコードブロックを同時に実行するスレッドが2つ以上ないことを確認しています。私はそれが可能で悪いことが起こることを知っているので、私は衝突を取得した後にロック()が追加されました。C#lock()、とにかくメトリックを取得するには?

ここでは、ロックがどのくらいの頻度でヒットしたかを判断するために使用できるフィードバック/カウンタを取得する方法を理解しようとしています。私はこの情報を得るためにMonitorクラスにフックする必要があると仮定していますが、誰かがこれを前に対処しているかどうか尋ねると思っていましたか?

+0

の可能性のある重複した[C#どのように物体を検出するが既にロックされている](HTTPS ://stackoverflow.com/questions/12033725/c-sharp-how-to-detect-an-object-is-already-locked) – Fruchtzwerg

+0

OPがネイティブロックメカニズムを再作成しようとしていたため、これは真の複製ではありません。この質問は、スレッドがロックリソースと競合する頻度を示すメトリックを取得することに関するものです。 –

答えて

3

あなたはしませんでした何回あなたがロックを得たか知りたいかどうかによって、次の2つのオプションがあります。

  1. を独自のパフォーマンスカウンタを書いて、あなたのロック文またはちょうどあなたの内側にそれを呼び出しますカウントするには単純な増分を使用します。
  2. Monitor.TryEnterをタイムアウトに使用し、指定した時間内にロックを取得しなかった回数をカウントします。
+0

#2とその他の質問[C#オブジェクトの検出方法は既にロックされています](https://stackoverflow.com/questions/12033725/c-sharp-how-to-detect-an-object-is-already-locked )これを行うための受け入れられた方法と思われる。ロックが必要なので、TryEnter()は成功するまでwhileループになります。何度もロックを取得できない場合は、カウンタを1回更新します。すべての提案に感謝します。 – Bob

2

performance countersを使用して、スレッドロック(合計の競合数)または1秒あたりの競合(競合率/秒)を取得するCLRの試行の失敗回数を特定できます。

https://msdn.microsoft.com/en-us/library/zf749bat(v=vs.110).aspx

注、これは総数であるので、あなたがあなたのアプリケーションで複数のスレッド競合シナリオを持っている場合は、このアプローチは、別のカウントにそれらを抜け出すことはありません。

Visual Studioに組み込まれているプロファイラを使用すると、並行性の問題に関する詳細情報を得ることができます。 VS 2015をご利用の場合は、Concurrency Visualizer(VS 2017ではまだ利用できません)をチェックしてください。

1

明白な、しかし数よりも有用であり得る、ロックで過ごしたどのくらいの時間を知らせます:

private long _lockTicks = 0; 

..... 

var sw = StopWatch.StartNew(); 
lock(_locker) 
{ 
    sw.Stop(); 
    _lockTicks += sw.ElapsedTicks; 
    //dostuff 
} 

...... 


double seconds = (double)_lockTicks/StopWatch.Frequency; 
関連する問題