Frage

I want to use an object-pool in my C# application, and I know that there isn't any reference count in C#. If the same object can be passed to several threads, how can I know when there are no more references to the object so that I can return it to the object pool?

I thought of doing it in the dispose method, but that is too late, and it can't be returned to the pool since it is disposed.

War es hilfreich?

Lösung

Implementing object-pool in .Net can be done using a Finalizer.

Actually, most of the pools implemented in .Net are doing this also (for example - DB connection pool).

Using a finalizer allows you to know that the object isn't referenced anymore, as the finalizer is being called after the GC determine that there are not possible routes to the object.

The technique is not to do any destructive methods in your Dispose (i'll be getting this next) and finalize method.

Let's say that you have an PooledObject type, and an ObjectPool type that manages the pool.

In the ObjectPool, add an internal methods called ReturnToPool(PooledObject obj) that will get the object and make it available for other callers.

In the PooledObject type, you should add an internal method called ReleaseResources - which will only be called by the ObjectPool when the entire pool should be removed from memory - in this method you will implement your dispose logic (closing handles, releasing un-managed memory, etc..). In the PooledObject Dispose and Finalize methods you should call the ReturnToPool methods in the ObjectPool (static, or internally stored in the pooled object) - this is called - resurrection. When calling the ReturnToPool method in the finalizer you are actually resurrecting the object and making it available again.

Make sure you are re-registering PooledObject for finalization in the ReturnToPool method in ObjectPool - GC.ReRegisterForFinalize method.

Both of those types should be in the same assembly, of course. (to make sure they can call each other internal methods)

You should however implement the Dispose pattern either way. It will save time when object is not being used anymore (after leaving Using scope for example) and will return the object to the pool.

Hope this helps. Ofir.

Andere Tipps

how can I know when there are no more references to the object so that I can return it to the object pool.

Hm. You implement reference counting.

What also works is a proxy around it that has a Disposable method. WHen done with the Proxy, the dispose implementation puts the inner object to the pool (the outer object tuhs is VERY small).

But at the end you have to know when to release. This is called programming. This only makes sense for "fat" objets with significant initialization overhead, and then you really have to make sure you acutally know when to put them back by logic (i.e. custom counting etc.).

It should be in the Close/Release method. Responsibility of creating and disposing the instance lies with the ObjectPool itself.

To request/release an object from/to ObjectPool, use Open/Close or Acquire/Release.

A The Code Project article, C# Object Pooling, presents a nice lightweight custom object pool implementation.

You can also look at Connection Pooling Mechanism of ADO.NET to get hint of an object pooling example.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top