C# 是否可以获取使用监视器等待的排队线程的计数。输入?
我运行的一些单例代码不是线程安全的,需要一些时间来运行。 它偶尔会被多个用户同时调用,所以我使用Monitor来处理处理请求队列,如下所示C# 是否可以获取使用监视器等待的排队线程的计数。输入?,c#,multithreading,locking,C#,Multithreading,Locking,我运行的一些单例代码不是线程安全的,需要一些时间来运行。 它偶尔会被多个用户同时调用,所以我使用Monitor来处理处理请求队列,如下所示 bool lockWasTaken = false; try { Monitor.TryEnter(lockObject, ref lockWasTaken); // returns lockWasTaken = true if it can get a lock if (!lockWasTaken) { log.Wa
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);
}
}
这一切都很好。但我想做的是能够记录有多少排队的请求。
这可能吗?感谢@Theodor Zoulias使用Interlocked类为下面的解决方案指出了正确的方向
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://docs.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);
}
如果(!lockwastake){块中有一个正在更新的静态变量,该怎么办?答案是没有。您是否查看了类以及方法
Increment
和Decrement
?您应该使用从interlocated.Increment(ref queueCount)返回的int;
而不是queueCount
本身,因为值可能在TryEnter
和日志警告之间更改。增量调用返回的int始终是增量后的新值。