c# - 如何检查信号量的状态

标签 c# .net multithreading semaphore

我想检查 Semaphore 的状态,看看它是否发出信号(所以如果 t 发出信号,我可以释放它)。我怎样才能做到这一点?

编辑 1:

我有两个线程,一个等待信号量,另一个应该释放一个信号量。问题是当第一个线程没有等待时,第二个线程可能会多次调用 Release()。因此,第二个线程应该检测到它是否调用 Release() 是否会产生任何错误(如果您尝试释放一个信号量而没有人在等待它,它会产生一个错误)。我怎样才能做到这一点?我知道我可以使用旗帜来做到这一点,但它很难看。有没有更好的办法?

最佳答案

您可以通过调用 WaitOne 并将超时值 0 作为参数传递来检查 Semaphore 是否发出信号。这将导致 WaitOne 立即返回 true 或 false 值,指示信号量是否已发出信号。当然,这可能会改变信号量的状态,这使得使用起来很麻烦。

这个技巧对您没有帮助的另一个原因是,据说当至少有一个计数可用时,信号量就会发出信号。听起来您想知道信号量何时具有所有可用计数。 Semaphore 类没有那种确切的能力。您可以使用 Release 的返回值来推断计数是多少,但这会导致信号量更改其状态,当然,如果信号量已经具有所有可用计数,它仍然会抛出异常在调用电话之前。

我们需要的是一个释放操作不会抛出的信号量。这并不难。如果计数可用,下面的 TryRelease 方法将返回 true,如果信号量已经达到 maximumCount,则返回 false。无论哪种方式,它都不会抛出异常。

public class Semaphore
{
    private int count = 0;
    private int limit = 0;
    private object locker = new object();

    public Semaphore(int initialCount, int maximumCount)
    {
        count = initialCount;
        limit = maximumCount;
    }

    public void Wait()
    {
        lock (locker)
        {
            while (count == 0) 
            {
                Monitor.Wait(locker);
            }
            count--;
        }
    }

    public bool TryRelease()
    {
        lock (locker)
        {
            if (count < limit)
            {
                count++;
                Monitor.PulseAll(locker);
                return true;
            }
            return false;
        }
    }
}

关于c# - 如何检查信号量的状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7330834/

相关文章:

c# - 从枚举中获取 DescriptionAttribute

c# - 自定义 DateTime 日长

c# 在 Windows 上更新仍在运行的程序

java - 迭代同步包装器是否安全?

java - 如果满足条件,则以原子方式写入两个变量

c# - 在 C# MySQL 语句中使用 LEFT() 使用 OdbcDataAdapter 填充 DataTable 时出错

c# - 为什么不能在成员初始值设定项中使用 'this'?

C# 运行时编译错误 : Type 'Double' and 'Math' could not be found/does not exist in current context

.net - 站点 "Notes And Attachments"的 Salesforce SOQL 查询

c# - SQL CLR 中的多线程缓存