除了在信号量上等待和释放外,C# 中是否有类似于 using() 的语法糖?

Is there a syntactic sugar in C# similar to `using()` except for taking waiting and releasing on a semaphore?

using (var foo = bar){} 是极好的语法糖。它替换了整个 blob

var foo = bar
try
{
}
finally
{
    foo.dispose()
}

我发现自己今天写了非常相似的 blob

var foo.WaitOne();
try
{
}
finally
{
    foo.release()
}

我想 C# 中没有类似的糖分吗?

查看 lock statement

lock 调用 Monitor.EnterMonitor.Exit,但它是唯一与线程同步相关的语法糖 blob-replacer。

这个问题的答案扩展得很好:How does lock work exactly?

没有。有一个用于 Monitor (lock) 但 none 用于信号量。

如果您确实需要,可以创建 helper disposable class 以将其与 using 一起使用,但它可能被视为滥用 IDisposable 模式。

正如 Alexei 所建议的那样,您最好的机会是使用实现 IDisposable.

的助手 class 来模拟所请求的行为

像这样应该就足够了:

public static class AutoReleaseSemaphoreExtensions
{
    // single threaded + idempotent Dispose version
    private sealed class AutoReleaseSemaphore : IDisposable
    {
        private readonly Semaphore _semaphore;

        private bool _disposed = false;

        public AutoReleaseSemaphore(Semaphore semaphore)
        {
            _semaphore = semaphore;
        }

        public void Dispose()
        {
            if(_disposed) return;
            _semaphore.Release();
            _disposed = true;
        }
    }

    public static IDisposable WaitOneAndRelease(this Semaphore semaphore)
    {
        semaphore.WaitOne();
        return new AutoReleaseSemaphore(semaphore);
    }
}

可以通过以下方式使用(感谢扩展方法):

var sem = new Semaphore(0, 1); // your semaphore here

using (sem.WaitOneAndRelease())
{
    // do work here
}
// semaphore is released outside using block.