简单的方法只允许一个线程访问C#中的资源?

时间:2011-11-26 22:29:53

标签: c# idisposable

如何替换此代码:

try
{
    lock (lockForSomethingInUse)
    {
        somethingInUse = true;
        // use it
    }
}
finally
{
    somethingInUse = false;
}

使用:

using (lockForSomething)
{
   // use it
}

4 个答案:

答案 0 :(得分:4)

lock()已经在引擎盖下生成了try / finally块,所以只需删除它就可以了。

答案 1 :(得分:1)

如果您想使用lock并且只能使用一个语句/变量知道当前是否实际获取了锁,您可以尝试使用以下类。他们不会因为可读性而赢得任何奖项,但他们允许您根据需要使用using进行锁定。

class DisposableLock
{
    public bool IsAcquired { get; set; }

    class Handle : IDisposable
    {
        private DisposableLock parent;

        public void Dispose()
        {
            parent.IsAcquired = false;
            Monitor.Exit(parent);
        }
    }

    public IDisposable Acquire()
    {
        var handle = new Handle();
        handle.parent = this;
        handle.parent.IsAcquired = true;
        Monitor.Enter(this);
        return handle;
    }
}

用法:

DisposableLock lockForSomething = new DisposableLock();
// ...

using (lockForSomething.Acquire())
{
// do something
}

然后,您可以在其他地方使用lockForSomething.IsAcquired来检查是否正在使用资源。实现IDisposable的内部类是为了确保您不会偶然使用using (lockForSomething)

答案 2 :(得分:0)

此代码:

using (lockForSomething) 
{ 
   // use it 
}

表示当使用代码块退出时会释放lockForSomething。除非lockForSomething属于更广泛的范围(不能不!),否则不同的线程就无法访问它。

答案 3 :(得分:0)

即使发生异常也不会失败,因为:

lock (x) ...

与:

相同
System.Threading.Monitor.Enter(x);
try {
   ...
}
finally {
   System.Threading.Monitor.Exit(x);
}

The lock statement on MSDN