简化 ReaderWriterLockSlim 语法

发布于 2024-11-25 08:17:01 字数 1630 浏览 1 评论 0原文

我最近不得不使用 ReaderWriterLockSlim 来同步对多个线程之间共享的多个资源的访问。在这样做的过程中,我觉得使用 ReaderWriterLockSlim 并不容易,特别是当你必须在多个地方使用它时。您必须有 try...finally 块并记住打开和关闭锁。在许多情况下,我还发现自己打开写锁并关闭读锁,而不是关闭写锁。因此,我尝试想出一种更简单的方法来使用 ReaderWriterLockSlim。这就是我

class Locked<T>
{
    private T _resource;
    private ReaderWriterLockSlim _lock;

    public Locked(T resource)
    {
        _resource = resource;
        _lock = new ReaderWriterLockSlim();
    }

    public void Read(Action<T> ReadAction)
    {
        try
        {
            _lock.EnterReadLock();
            ReadAction(_resource);
        }
        finally
        {
            _lock.ExitReadLock();
        }
    }

    public void Write(Action<T> WriteAction)
    {
        try
        {
            _lock.EnterWriteLock();
            WriteAction(_resource);
        }
        finally
        {
            _lock.ExitWriteLock();
        }
    }
}

现在得到的地方,例如,如果我们需要同步对 List 的访问,这就是我们使用上面的类来实现的方法,

public class Demo
{
    private Locked<List<string>> _listOfString;

    public Demo()
    {
        _listOfString = new Locked<List<string>>(new List<string>());
    }

    public void writeMethod(string value)
    {
        _listOfString.Write(list =>
        {
            list.Add(value);
        });
    }

    public string readMethod(int index)
    {
        string value = null;
        _listOfString.Read(list =>
        {
            value = list[index];
        });
        return value;
    }
}

您认为这种方法更好吗?有没有什么缺点或者缺陷。

I recently had to use ReaderWriterLockSlim to synchronize access to several resources that are shared between multiple threads. While doing it, I felt that using ReaderWriterLockSlim is not easy specially when you have to use it in multiple places. You have to have try...finally blocks and remember to open and close the locks. In many cases I've also found myself opening a write lock and closing a read lock instead of closing the write lock. Therefore I tried to come up with an easier way of using the ReaderWriterLockSlim. This is where I got

class Locked<T>
{
    private T _resource;
    private ReaderWriterLockSlim _lock;

    public Locked(T resource)
    {
        _resource = resource;
        _lock = new ReaderWriterLockSlim();
    }

    public void Read(Action<T> ReadAction)
    {
        try
        {
            _lock.EnterReadLock();
            ReadAction(_resource);
        }
        finally
        {
            _lock.ExitReadLock();
        }
    }

    public void Write(Action<T> WriteAction)
    {
        try
        {
            _lock.EnterWriteLock();
            WriteAction(_resource);
        }
        finally
        {
            _lock.ExitWriteLock();
        }
    }
}

Now for e.g. if we need to synchronize access to a List<string> this is how we do it using the class above

public class Demo
{
    private Locked<List<string>> _listOfString;

    public Demo()
    {
        _listOfString = new Locked<List<string>>(new List<string>());
    }

    public void writeMethod(string value)
    {
        _listOfString.Write(list =>
        {
            list.Add(value);
        });
    }

    public string readMethod(int index)
    {
        string value = null;
        _listOfString.Read(list =>
        {
            value = list[index];
        });
        return value;
    }
}

Do you think this approach is any better? Are there any shortcomings or flaws.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

哆兒滾 2024-12-02 08:17:01

我宁愿将锁定逻辑包装在 IDisposable 中,并将要锁定的代码放在 using 块中,与 lock 语句非常相似:

class DisposableLock : IDisposable
{
    Action _exitLock;
    public DisposableLock(Action exitLock)
    {
        _exitLock = exitLock;
    }

    public void Dispose()
    {
        _exitLock();
    }
}

class ReadLock : DisposableLock
{
    public ReadLock(ReaderWriterLockSlim slimLock)
        : base(() => slimLock.ExitReadLock())
    {
        slimLock.EnterReadLock();
    }
}

class WriteLock : DisposableLock
{
    public WriteLock(ReaderWriterLockSlim slimLock)
        : base(() => slimLock.ExitWriteLock())
    {
        slimLock.EnterWriteLock();
    }
}

您可以像这样使用它:

using(new ReadLock(_lock))
{
    // ... your synchronized operation
}

using(new WriteLock(_lock))
{
    // ... your synchronized operation
}

I would rather wrap the locking logic in an IDisposable and put the code you want to lock in a using block, very similar to the lock statement:

class DisposableLock : IDisposable
{
    Action _exitLock;
    public DisposableLock(Action exitLock)
    {
        _exitLock = exitLock;
    }

    public void Dispose()
    {
        _exitLock();
    }
}

class ReadLock : DisposableLock
{
    public ReadLock(ReaderWriterLockSlim slimLock)
        : base(() => slimLock.ExitReadLock())
    {
        slimLock.EnterReadLock();
    }
}

class WriteLock : DisposableLock
{
    public WriteLock(ReaderWriterLockSlim slimLock)
        : base(() => slimLock.ExitWriteLock())
    {
        slimLock.EnterWriteLock();
    }
}

You would use it like this:

using(new ReadLock(_lock))
{
    // ... your synchronized operation
}

using(new WriteLock(_lock))
{
    // ... your synchronized operation
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文