2

スレッドがに到着したときにスレッドがロックを待機していることをログに記録する簡単な方法はありますか?

lock(x)
{
  //do work on a collection

}

スレッド1がロックに到達し、ブロック内に別のスレッドがない場合、ログはありません。次に、スレッド2がlock(x)に到達し、スレッド1がまだブロック内にある場合は、ログが存在するはずです。理想的なソリューションでは、ミューテックスまたはモニターに切り替える必要がなく、複雑さが増します。TPL、PLINQ、またはRXを使用してこれを行うための迅速で簡単な方法があれば、それは素晴らしいことです。

4

3 に答える 3

10

ステートメントの糖分lockを取り除き、 Monitor.TryEnterを使用して、待機せずにロックを取得できるかどうかを確認できます。

bool lockTaken = false;
var obj = x;
try
{
    Monitor.TryEnter(obj, ref lockTaken);
    if (!lockTaken)
    {
        Log();
        Monitor.Enter(obj, ref lockTaken);
    }
    //do work on a collection
}
finally
{
    if (lockTaken)
    {
        Monitor.Exit(obj);
    }
}
于 2011-10-12T15:32:10.403 に答える
2

なぜあなたはこれをしようとしているのですか?デバッグまたはプロファイリングを目的としている場合は、アンマネージCLRプロファイリングまたはデバッグAPIを使用できます。もう1つの考えは、PostSharpやAfterthoughtなどのツールを使用してコンパイルした後、ILコードを静的に変更することです。(Afterthoughtは現在の形式ではこれを行うことができないことに注意してください。ただし、ソースがあるため、これをハックすることができます。)

代わりにコードを変更することをお勧めします。dtbの構文の代わりにこれをお勧めします:

if (!Monitor.TryEnter(x))
{
    Log();
    Monitor.Enter(x);
}
try
{
    //do work on a collection
}
finally
{
    Monitor.Exit(x);
}
于 2011-10-12T15:48:55.577 に答える
2

lock()標準のステートメントではこれを簡単に行うことはできません。を使用Monitor.TryEnter()してロックの入力を試み、メソッドがを返した場合は何かをログに記録できますfalse

于 2011-10-12T15:30:48.640 に答える