How do I implement class finalization?

  • Thread starter Thread starter JollyK
  • Start date Start date
J

JollyK

Hello everyone,
I have a abstract class called DalBase and in that class I have a couple of
methods. One of the method that I have is called BeginTran() and this class
initializes a private Transaction object. I also have a method called
CommitTran() that disposes the private Transaction object, thus setting it
to null. Now the issue is, if the user calls BeginTran, I have to make sure
he/she calls CommitTran() so that the private transaction object gets set to
null. The only way I can think of is using C# distructor.

So I have coded

Code:
~DalBase()
{
if (this._transaction != null)
{
throw (new Exception("You have opened a transaction that needs to be
closed."));
}
}

Now I have checked when I run the application, and call BeginTran() method
and intentionally not call CommitTran(), the above code does not get
executed. But if I set a break point at the above code, then it gets
executed. This is probably something to do with garbage collection. But how
do I solve the problem I am having. A short example would be very helpful.
Thanx alot
 
For scenarios like these you're probably better off using a
ServicedComponent inside COM+ (nee EnterpriseServices). You can rely on the
Activate and Deactivate methods being invoked by COM+ and you can then
release your resources.

The other way is to force your clients to call Dispose() on instances of
types derived from your base class.
 
I have a vague memory that the finalizers aren't guaranteed to be run when a
program exits, but I'm willing to be corrected about that.

You could try putting GC.Collect() and GC.WaitForPendingFinalizers() near
the very end of your program. I wouldn't put them anywhere else in your
code, except perhaps for debugging, as they have obvious performance
penalties.

You might want to consider a slightly different pattern for your transaction
class:

class Transaction : IDisposable
{
protected Transaction()
{
_realTransaction = new RealTransaction();

_realTransaction.BeginTran();
}

~Transaction()
{
Debug.Assert("not disposed correctly");
}

public void Dispose()
{
if(_realTransaction != null)
{
_realTransaction.Rollback();
}
GC.SuppressFinalize(this);
}

public void Commit()
{
Debug.Assert(_realTransaction != null, "already commited or
disposed");

_realTransaction.Commit();
_realTransaction = null;
}

private _realTransaction;
}

and then you can use them like:

using(Transaction transaction = someFactory.CreateTransaction())
{
// Do some stuff here

// Do we want to commit
if(itsAllOK)
{
transaction.Commit();
}

} // The real transaction will either be rolled back or committed.

Of course there are several variants (eg not storing the real transaction
object but using abstract protected methods instead, with the actual
transaction processing carried out by the derived class).

It's a pattern I've found useful, hope it helps you too.

Stu
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top