2014-03-12 35 views
0

我在管理多个模块中的资源时遇到了一些问题,这些模块只能安全地访问一次。异常后的信号灯超时

所以我尝试了一个名为Semaphore这样的:

var semaphore = new Semaphore(1, 1, "_UGLY_SEMAPHORE_NAME_"); 

     try 
     { 
      var signaled = semaphore.WaitOne(120000); // 2 minutes 

      if (!signaled) 
      { 
       return; 
      } 

      // Access the resource... 
     } 
     finally 
     { 
      semaphore.Release(); 
     } 

在其他模块我用

var signaled = semaphore.WaitOne(0); 

,因为如果没有其他事情做资源只能被访问。 6秒后稳定返回,所以2分钟应该足够我相信。

所以,问题是:

如果第一个代码块,事后Semaphore.WaitOne(发生异常) 经常遇到超时。有什么我做错了。

+0

哪里发生异常?它是在“//访问资源...”,还是在谈论奇怪的边缘情况,并在异常的地方使用类似线程异常终止的异常? – Servy

+0

是的。它在该代码之外被处理,并且最终被调用。我对“发布递增和WaitOne递减”部分感到困惑。 –

+0

然后查看“Semaphore”的文档,或者查看Google上的文档;这是一个相当明确的CS概念。 – Servy

回答

0

处理过程中发生异常不是导致等待信号量的任何其他线程等待超时。 finally块的语义意味着,如果异常导致try块结束,它将执行,从而释放信号量。

+0

那么,为什么第二次进入异常后的第一个代码块时会进入超时?我很确定这是关于我在使用WaitOne和Release时所做的,但我无法弄清楚。 –

+0

@MareInfinitus然后要么你没有显示你使用的实际代码,要么你没有正确地观察结果。 – Servy

+0

问题中的代码是我正在使用的代码,并且我正在观察该行为。所以你认为它应该如上所示? –

0

我怀疑问题在于,无论线程是否进入信号量,您都在调用sempahore.Release()。如果代码路径进入信号量,则应该只调用Release,否则在您没有获取信号时释放信号量时可能会抛出计数器。

var semaphore = new Semaphore(1, 1, "_UGLY_SEMAPHORE_NAME_"); 

var signaled = semaphore.WaitOne(120000); // 2 minutes 

if (!signaled) 
{ 
    return; 
} 
try 
{ 
    // Access the resource... 
} 
finally 
{ 
    semaphore.Release(); 
}