Extending the SqlDataAdapter with a FillTimeout

The SqlDataAdapter has a CommandTimeout property but does offer any method to set any kind of timeout during the Fill method. If you are returning rather large data sets, you can quickly run into a problem. The obvious solution would be to inherit the SqlDataAdapter and simply override the Fill method, except that the SqlDataAdapter cannot be inherited. As a result, we must implement the same methods that the SqlDataAdapter does and attach them to a private internal SqlDataAdapter to do all the heavy lifting. With the use of anonymous delegates, we can easily rework the Fill methods to offer a new FillTimeout property and throw an exception when we exceed our desired timeout.

public int FillTimeout
{
    get { return _fillTimeout; }
    set { _fillTimeout = value; }
}

public int Fill(DataSet dataSet)
{
    if (_fillTimeout == 0)
    {
        return _adapter.Fill(dataSet);
    }
    else
    {
        int rows = 0;
        Thread fillThread = new Thread(delegate() { rows = _adapter.Fill(dataSet); });
        fillThread.Start();
        if (fillThread.Join(_fillTimeout * 1000))
        {
            return rows;
        }
        else
        {
            try
            {
                fillThread.Abort();
            }
            catch (ThreadAbortException)
            {
                Thread.ResetAbort();
            }
            throw new TimeoutException();
        }
    }
}

Download the full ExtendedSqlDataAdapter class : ExtendedSqlDataAdapter.cs

Leave a comment

Your email address will not be published. Required fields are marked *