SafeDataReader, IDisposable and Undeterministic Destruction

SafeDataReader, IDisposable and Undeterministic Destruction

Old forum URL: forums.lhotka.net/forums/t/2752.aspx


William posted on Monday, April 23, 2007

I am giving some thoughts on SafeDataReader.

SafeDataReader implements IDataReader and IDisposable. In C#, best practice when using disposable objects is to explicitly call the Dispose() method when you are done. Typically, in DataPortal_Fetch() method of CSLA business objects,

protected override void DataPortal_Fetch(object criteria)
{
    ...
    using (SafeDataReader dr = new SafeDataReader(cmd.ExecuteReader))
    {
       // Fetch data.

       dr.NextResult();
       _childObject.Fetch(dr);
    }
}


Then, in the child object, I would like to maintain the genericity of using IDataReader instead of SafeDataReader. The primary reason is that this allows flexibility in switch between real DataReader and DataTableReader, which both implements IDataReader.

internal void Fetch(IDataReader dr)
{
    using (SafeDataReader sdr = new SafeDataReader(dr))
    {
       ...
    }
}

This pattern will close the underlying data reader when the using block exits - correct practice, but it also closes the underlying data reader, which it is not supposed to.

Another way,

internal void Fetch(IDataReader dr)
{
    SafeDataReader sdr = new SafeDataReader(dr);

    // Fetch data and return. No Dispose() call.
}

This version does not explicitly call the Dispose method. However, the destructor of SafeDataReader does call Dispose method. It is undetermined when the destructor will be called, which I think will close the underlying data reader in an unattended manner.

I am concerning if I am using SafeDataReader in the correct way or there are other special considerations I need to be aware of.

Please advise.

Regards,
William

William replied on Monday, April 23, 2007

Rocky,

What is the intended and correct usage of SafeDataReader for the scenario described above?

Regards,
William

Brian Criswell replied on Monday, April 23, 2007

William:

internal void Fetch(IDataReader dr)
{
    using (SafeDataReader sdr = new SafeDataReader(dr))
    {
       ...
    }
}

In my opinion, there is no reason to pass an IDataReader if you are immediately going to wrap it in a SafeDataReader again.  Just pass the SafeDataReader from parent to child.

Copyright (c) Marimer LLC