2

我有一堂课MyClass。这个类有一个字段:(public ReaderWriterLockSlim rw;公共的更简单的示例代码)。MyClass许多线程可以从usingrw.EnterReadLock等 中读取数据。

我也实现了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当第二个线程调用DisposemyClass 对象时,一个线程正在使用。我无法处置 ReaderWriterLockSlim,因为它会使我的应用程序崩溃。那么我应该删除那些释放托管资源的行吗?反正 ReaderWriterLockSlim 会在不久的将来被 GC 收集,对吧?(但是这个类资源贵吗?)。
也许我应该在 Dispose 方法或其他东西中添加一些 lock(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
}
4

1 回答 1

1

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

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

如果调用了 dispose 方法,则意味着任何其他对象都不应该使用该对象。这意味着您必须首先确保所有线程首先完成对对象的操作,然后再调用 dispose 方法。

建议

  • 将锁设为私有
  • 在调用 dispose 之前确保所有线程都已完成
  • 为安全行为添加超时
  • 考虑使用静态锁对象
  • ReaderWriterLockSlim 资源并不昂贵(到了您应该在应用程序中关心的程度)
  • 如果你的类使用一次性资源,通常最好实现 IDisposable 并处理需要处理的成员。
  • 不要在 Dispose 方法中添加任何锁,它应该很简单。这可能会引入令人不快的错误。因为如果您忘记手动调用 Dispose,GC 将不确定地调用它(通过 finiliser,您也应该添加它以调用 Dispose)
  • 正确的方法是等到所有线程都完成并处置一个对象
于 2013-02-03T11:09:40.340 回答