是否可以获取使用 Monitor.Enter 等待的排队线程计数?



我正在运行一些线程不安全的单例代码,需要一些时间才能运行。 它偶尔可以由多个用户同时调用,因此我使用 Monitor 来处理处理请求队列,如下所示;

bool lockWasTaken = false;
try
{
Monitor.TryEnter(lockObject, ref lockWasTaken); // returns lockWasTaken = true if it can get a lock
if (!lockWasTaken)
{
log.Warn("Locked by existing request. Request is queued.");
Monitor.Enter(lockObject, ref lockWasTaken); // Goes into the queue to access the object
}
// Do the Singleton processing
}
catch(Exception ex)
{
log.Fatal(ex);
}
finally
{
if (lockWasTaken)
{
Monitor.Exit(lockObject);
}
}

这一切都很有效。但我想做的是能够记录有多少排队的请求。 这可能吗?

感谢 Zoulias @Theodor使用互锁类为我指出以下解决方案的正确方向;

private static readonly Object lockObject = new Object(); // just a random object used to decide whether the thread has locked the Singleton functions
private static int queueCount = 0; // tracked across multiple threads
bool lockWasTaken = false;
try
{
// Increments the queueCount variable across multiple threads
// https://learn.microsoft.com/en-us/dotnet/api/system.threading.interlocked.increment?view=netframework-4.8
int currentQueueCount = Interlocked.Increment(ref queueCount);
Monitor.TryEnter(lockObject, ref lockWasTaken); // returns lockWasTaken = true if it can get a lock
if (!lockWasTaken)
{
log.Warn("Locked by existing request. Request is queued. Queue length is " + (currentQueueCount - 1).ToString()); // subtract since the first request is already processing
Monitor.Enter(lockObject, ref lockWasTaken); // Goes into the queue to access the object
}
// Do the Singleton processing
}
catch(Exception ex)
{
log.Fatal(ex);
}
finally
{
if (lockWasTaken)
{
Monitor.Exit(lockObject);
}
// Reduce the queue count
Interlocked.Decrement(ref queueCount);
}

最新更新