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)
看起来你需要一个其他的同步对象,因为Semaphore没有提供这样的功能来检查它是否在特定的时刻发出信号.
信号量允许自动触发代码,WaitOne()/Release()例如使用方法等待信号状态.
你可以看一下暴露CurrentCount属性的新.NET 4类SemaphoreSlim,也许你可以利用它.
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)