IDisposable and ReaderWriterLockSlim
本文关键字:ReaderWriterLockSlim and IDisposable | 更新日期: 2023-09-27 17:57:25
我有一个类MyClass
.此类有一个字段:public ReaderWriterLockSlim rw;
(公共,用于更简单的示例代码)。许多线程可以使用rw.EnterReadLock
等从MyClass
读取数据。
我也实现了IDisposable
接口:
private void Dispose (bool pDisposing)
{
{
if (pDisposing) // release managed resources
{
if (rw != null)
{
rwLockSlim.Dispose ();
rwLockSlim = null;
}
}
//--- release unmanaged resources
// some code...
isDisposed = true; // ...
}
}
如您所见,问题在于当一个线程使用 MyClass
时,当第二个线程调用 myClass 对象Dispose
时。我无法处理 ReaderWriterLockSlim,因为它会使我的应用程序崩溃。那么我是否应该删除释放托管资源的行?无论如何,ReaderWriterLockSlim将在不久的将来被GC收集,对吧?(但是这个类资源贵吗?
也许我应该在 Dispose metod 或其他东西中添加一些锁(syncObject)?
编辑:我也处理 AllocHGlobal,所以我需要等待,直到所有线程停止读取/写入myClass
。
不同观点:
public MyClass : IDisposable
{
public void EnterReadLock (); // calls rwLockSlim.EnterReadLock,
// if object is disposed throws Exception
public void ExitReadLock (); // same as above
public void Dispose (); // wait until all threads exit from locks,
// frees unamanged resources, mark class as disposed
}
这可能不是最好的答案,而是观察和一些想法。
你能简化你的代码吗?我的意思是,其他类型不应该关心您的类型是否在特定并发条件下引发异常。您将如何测试这一点?公共锁对象是邪恶的。它必须是私密的,除非你想花几个月的时间试图找出神秘的错误。
如果调用了 dispose 方法,则意味着其他对象不应使用此对象。这意味着在调用 dispose 方法之前,必须首先确保所有线程都首先完成对对象的操作。
建议
- 将锁设为私有
- 在调用释放之前,确保所有线程都已完成
- 为安全行为添加超时
- 考虑使用静态锁定对象
- ReaderWriterLockSlim 的资源并不昂贵(在应用程序中您应该关注这一点)
- 如果您的类使用一次性资源,通常最好实现 IDisposable 并释放需要释放的成员。
- 不要在 Dispose 方法中添加任何锁,它应该很简单。这可能会引入令人不快的错误。因为如果您忘记手动调用 Dispose,GC 将不确定地调用它(通过 finiliser,您也应该添加它来调用 Dispose)
- 正确的方法是等到所有线程都完成并释放一个对象