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

本文关键字:资源 简单 方法 访问 线程 许一个 | 更新日期: 2023-09-27 18:16:03

如何替换这段代码:

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

:

using (lockForSomething)
{
   // use it
}

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

lock()已经生成了try/finally块,所以只要删除它,一切都会好的

如果您想使用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)

代码:

using (lockForSomething) 
{ 
   // use it 
}

表示当using代码块退出时,lockForSomething被处理。除非lockForSomething属于更广泛的作用域(不不!),否则其他线程无法访问它。

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

lock (x) ...

等于:

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

MSDN上的锁语句