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