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()
}
is the above safe + clean? Will the both _sync get disposed and myclass be collected when all 100 threads have finished doing their async work?
If not, what's the best way to know when to call _sync.Dispose() ?
Short answer: No, you don't need to call Dispose().
Long answer:
Though it is recommended to call Dispose() when you are finished using the Semaphore, the garbage collector will take care of the semaphore's resources sooner or later.
An explicit call to Dispose() will guarantee an early release of the associated resource, but it's only required if you are creating and forgetting a lot of Semaphore instance in a short amount of time.
And if you call Dispose(), it is perfectly fine to use a simple Dispose() call. You don't need to create a finalizer ~myclass()
because that would just duplicate what's already done the Semaphore implementation.
If a class implements IDisposable, you really should dispose of it correctly. It is not just about relying on the garbage collector, the disposable class could have open handles / COM objects that need to be correctly cleaned up that you cannot guarantee that the GC will handle.
Ideally you should make myclass
implement IDisposable and clean up your disposable objects in the dispose method. If you truly cannot determine when to dispose your instance of myclass
then you can implement logic in the destructor method for myclass
to call the dispose method.
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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With