私はスレッドの専門家ではありませんが、他のスレッドがオブジェクトを処理しようとした回数を取得するには、おそらくより原始的なバージョンのロックメカニズムを実装する必要がありLock
ます。しっかりとループしたモニターを使って、以下のショットを撮りました。TryEnterとコメントを歓迎します。
もちろん、このようなものを単独で実装すると、必要なカウントを取得するために、またこの実装が内部でのロックの動作とはまったく同じではないという事実に基づいて、ブロック時間が長くなり、ブロックが増える可能性があります。とにかく時間を費やしたので投稿します。
class Program
{
static object lockObj = new object();
static void Main(string[] args)
{
System.Threading.Thread t = new System.Threading.Thread(proc);
System.Threading.Thread t2 = new System.Threading.Thread(proc);
t.Start();
t2.Start();
t.Join();
t2.Join();
Console.WriteLine("Total locked up time = " + (LockWithCount.TotalWaitTicks / 10000) + "ms");
Console.WriteLine("Total blocks = " + LockWithCount.TotalBlocks);
Console.ReadLine();
}
static void proc()
{
for (int x = 0; x < 100; x++)
{
using (new LockWithCount(lockObj))
{
System.Threading.Thread.Sleep(10);
}
}
}
}
Lock() {}
上記は、既存のものをで置き換えることによってLockWithCountを使用する方法を示していますusing(new LockWithCount(x)) {}
class LockWithCount : IDisposable
{
static System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
object lockObj;
public static long TotalWaitTicks = 0;
public static long TotalBlocks = 0;
static LockWithCount()
{
watch.Start();
}
public LockWithCount(object obj)
{
lockObj = obj;
long startTicks = watch.ElapsedTicks;
if (!System.Threading.Monitor.TryEnter(lockObj))
{
System.Threading.Interlocked.Increment(ref TotalBlocks);
System.Threading.Monitor.Enter(lockObj);
System.Threading.Interlocked.Add(ref TotalWaitTicks, watch.ElapsedTicks - startTicks);
}
}
public void Dispose()
{
System.Threading.Monitor.Exit(lockObj);
}
}