C# NET中是否有线程锁的低级度量/日志记录?

C# NET中是否有线程锁的低级度量/日志记录?,c#,.net,multithreading,logging,locking,C#,.net,Multithreading,Logging,Locking,多年来,如果存在的话,我还没有真正遇到过这个问题,所以我把它放在这里是为了了解是否有人知道任何低级的.NET功能,可能在反射中,可以在线程被锁定时捕获?也许是某种日志记录 private object _lockObject = new object(); void MyFunc() { lock(_lockObject) // <== How can I understand how many threads are waiting on this? { // Do w

多年来,如果存在的话,我还没有真正遇到过这个问题,所以我把它放在这里是为了了解是否有人知道任何低级的.NET功能,可能在反射中,可以在线程被锁定时捕获?也许是某种日志记录

private object _lockObject = new object();

void MyFunc()
{
  lock(_lockObject) // <== How can I understand how many threads are waiting on this?
  {
    // Do work
  }
}

你可以通过互联网获得一些信息

为此,您需要知道要监视的进程的名称

性能计数器类别名称为“
”.NET CLR LocksAndThreads“
,该类别的计数器名称显示在上面链接的页面上的表格中

监视通常从与被监视进程不同的进程执行,但为简单起见,这里有一个监视自身的示例控制台应用程序:

using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main()
        {
            var counter1 = new PerformanceCounter(".NET CLR LocksAndThreads", "Contention Rate / sec",  "ConsoleApp1");
            var counter2 = new PerformanceCounter(".NET CLR LocksAndThreads", "Total # of Contentions", "ConsoleApp1");

            Task.Run(() => test());
            Task.Run(() => test());
            Task.Run(() => test());
            Task.Run(() => test());

            while (true)
            {
                Thread.Sleep(100);
                Console.WriteLine($"Contention: {counter1.NextValue()}/sec, Total: {counter2.NextValue()}");
            }

        }

        static object locker = new object();

        static void test()
        {
            while (true)
            {
                lock (locker)
                {
                    Thread.Sleep(50);
                }
            }
        }
    }
}

这个解决方案对于所有锁的总体情况非常有效,我想没有更细粒度的计数器来理解每个锁,因为lock()没有“命名”功能。我必须用
Process.GetCurrentProcess().ProcessName
替换ConsoleApp1以使其在调试模式下工作。@ajb101抱歉,但据我所知不是这样。多亏了MickyD,一个信号量似乎不符合我的目标,因为您通常为一个函数设置一个信号量,我希望了解所有锁都发生了什么。除非你有别的想法并且能提供一个例子?
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main()
        {
            var counter1 = new PerformanceCounter(".NET CLR LocksAndThreads", "Contention Rate / sec",  "ConsoleApp1");
            var counter2 = new PerformanceCounter(".NET CLR LocksAndThreads", "Total # of Contentions", "ConsoleApp1");

            Task.Run(() => test());
            Task.Run(() => test());
            Task.Run(() => test());
            Task.Run(() => test());

            while (true)
            {
                Thread.Sleep(100);
                Console.WriteLine($"Contention: {counter1.NextValue()}/sec, Total: {counter2.NextValue()}");
            }

        }

        static object locker = new object();

        static void test()
        {
            while (true)
            {
                lock (locker)
                {
                    Thread.Sleep(50);
                }
            }
        }
    }
}