IDisposable和ReaderWriterLockSlim

时间:2013-02-03 10:36:10

标签: c# idisposable readerwriterlockslim

我有一个班级MyClass。这个类有一个字段:public ReaderWriterLockSlim rw;(public是一个更简单的示例代码)。许多线程可以使用MyClass等从rw.EnterReadLock读取数据。

我也实现了IDisposable interface:

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,因为它会导致我的应用程序崩溃。那么我应该删除那些释放托管资源的行吗?无论如何,在不久的将来,GC将收集ReaderWriterLockSlim,对吧? (但这类资源是否昂贵?) 也许我应该在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
}

1 个答案:

答案 0 :(得分:1)

这可能不是最好的答案,而是观察和一些想法。

您可以简化代码吗?我的意思是,其他类型不应该关心你的类型是否在特定的并发条件下抛出异常。你将如何测试?公共锁定对象是邪恶的。 必须是私有的,除非您想花费数月时间试图找出神秘的错误。

如果调用dispose方法,则意味着没有其他对象应该使用此对象。这意味着在调用dispose方法之前,必须首先确保所有线程首先完成对对象的操作。

建议

  • 将锁定设为私有
  • 在调用dispose
  • 之前,确保所有线程都已完成
  • 为安全行为添加超时
  • 考虑使用 static 锁定对象
  • ReaderWriterLockSlim资源不贵(在您的应用程序中应该关注的程度)
  • 如果您的班级使用一次性资源,通常最好实施IDisposable并处置需要处理的成员。
  • 不要在Dispose方法中添加任何锁,它应该很简单。这可能会引入令人不快的错误。因为如果你忘记手动调用Dispose,GC会不确定地调用它(通过一个finiliser,你也应该添加它来调用Dispose)。
  • 正确的方法是等待所有线程完成并处理一个对象