10
class myclass 
{
    private Semaphore _sync;

    myclass ()
    {
          _sync = new Semaphore(1,1);
    }

    doasync()
    {
           _sync.WaitOne();
           //do some stuff
           _sync.Release();
    }
}


 somefunctionsomewhere() 
 {
     var myobject = new myclass();    
     //spawn 100 threads that all call myobject.doasync()
 }

以上安全+干净吗?当所有 100 个线程都完成它们的异步工作时,是否会同时处理 _sync 和 myclass ?

如果没有,知道何时调用 _sync.Dispose() 的最佳方法是什么?

4

2 回答 2

11

简短回答:不,您不需要调用 Dispose()。

长答案:

虽然建议您在使用完信号量后调用 Dispose(),但垃圾收集器迟早会处理信号量的资源。

显式调用 Dispose() 将保证相关资源的早期释放,但仅当您在短时间内创建并忘记大量 Semaphore 实例时才需要它。

如果您调用 Dispose(),那么使用简单的 Dispose() 调用就可以了。您不需要创建终结器~myclass(),因为这只会复制已经完成的 Semaphore 实现。

于 2012-11-19T12:22:59.297 回答
3

如果一个类实现了 IDisposable,你真的应该正确地处理它。这不仅仅是依赖垃圾收集器,一次性类可能具有需要正确清理的打开句柄/COM 对象,您不能保证 GC 会处理。

理想情况下,您应该myclass实现 IDisposable 并在 dispose 方法中清理一次性对象。如果您确实无法确定何时释放您的实例,myclass那么您可以在析构函数中实现逻辑myclass以调用 dispose 方法。

public class myclass : IDisposable
   {
   private Semaphore _sync;

    myclass ()
    {
          _sync = new Semaphore(1,1);
    }

    doasync()
    {
           _sync.WaitOne();
           //do some stuff
           _sync.Release();
    }

    public void Dispose()
       Dispose(true);
       GC.SuppressFinalize(this);
    {

    protected void Dispose(bool isDisposing)
    {
       var sync=Interlocked.Exchange(ref _sync,null);
       if (sync !=null) sync.Dispose();
    }


    // This is for when you cannot determine when to dispose of your object
    void ~myclass() {
       Dispose(false);
    }
}
于 2012-11-19T12:04:15.220 回答