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