如何检查信号量的状态

man*_*ans 17 .net c# multithreading semaphore

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

EDIT1:

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

Bri*_*eon 14

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

这个技巧无法帮助你的另一个原因是因为当至少有一个计数可用时,就会发信号通知信号量.听起来你想知道信号量何时可用.这Semaphore门课没有那种确切的能力.您可以使用返回值Release来推断计数是什么,但这会导致信号量改变其状态,当然,如果信号量在进行调用之前已经具有所有可用计数,它仍然会抛出异常.

我们需要的是具有不抛出的释放操作的信号量.这并不十分困难.TryRelease如果计数可用,则下面的方法将返回true;如果信号量已经存在,则返回false maximumCount.无论哪种方式,它都不会抛出异常.

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


sll*_*sll 7

看起来你需要一个其他的同步对象,因为Semaphore没有提供这样的功能来检查它是否在特定的时刻发出信号.

信号量允许自动触发代码,WaitOne()/Release()例如使用方法等待信号状态.

你可以看一下暴露CurrentCount属性的新.NET 4SemaphoreSlim,也许你可以利用它.

CurrentCount
获取允许进入SemaphoreSlim的线程数.

编辑:由于更新的问题更新

作为一个快速解决方案,您可以semaphore.Release()通过try/catch和handle 进行包装SemaphoreFullException,它是否按预期工作?

使用SemaphoreSlim你可以这样检查CurrentCount:

 int maxCount = 5;
 SemaphoreSlim slim = new SemaphoreSlim(5, maxCount);            

 if (slim.CurrentCount == maxCount)
 {
    // generate error
 }
 else
 {
   slim.Release();
 }
Run Code Online (Sandbox Code Playgroud)