Przez długi czas miałem problem z pewną aplikacją w ASP.NET, a konkretnie z pewnym żądaniem do serwera. W niektórych wywołaniach, serwer po 30 sekundach działania, zwracał error code 500 (internal server error). W pierwszym odruchu, moja uwaga skupiła się na analizie timeout'ów po stronie aplikacji ASP: sesje, pule aplikacji. Jednak, jak się później okazało, problem leżał w wywołaniu zapytania do bazy SQL. W dostępie do bazy wykorzystuję DataSety. Okazuje się, że każdy obiekt klasy TableAdapter ma domyślnie ustawioną właściwość CommandTimeout na wartości 30 sekund. Problem w tym, że właściwość ta jest protected i nie ma bezpośredniej możliwości modyfikacji jej wartości. Rozwiązaniem jest nadpisanie właściwości CommandTimeout w klasie rozszerzającej (klasy TableAdapter są oznaczone jako 'partial'). Przykładowy kod realizujący to zadanie:
namespace esklep_mag.DataSets {
public partial class MyDS {
}
}
namespace esklep_mag.DataSets.MyDSTableAdapters
{
public partial class QueriesTableAdapter
{
public int CommandTimeout
{
set
{
for (int i = 0; (i < this.CommandCollection.Length); i = (i + 1))
{
if ((this.CommandCollection[i] != null))
{
this.CommandCollection[i].CommandTimeout = value;
}
}
}
}
}
}
(najprostszą metodą na wygenerowanie tej klasy w osobnym pliku jest otworzenie DataSet'a w designerze, kliknięcie prawym przyciskiem myszy na wybranym adapterze i wybranie 'View code')
Tak przygotowany adapter możemy wykorzystać w kodzie tak:
DataSets.MyDSTableAdapters.QueriesTableAdapter qta = new esklep_mag.DataSets.MyDSTableAdapters.QueriesTableAdapter();
qta.CommandTimeout = 480;
qta.GetData(...
W przypadku korzystania z adaptera jako źródła danych dla obiektu klasy ObjectDataSource, ustawienia czasu trwania zapytania możemy dokonać w zdarzeniu:
protected void ObjectDataSource1_ObjectCreated(object sender, ObjectDataSourceEventArgs e)
{
DataSets.TestsDBTableAdapters.QueriesTableAdapter qAda = e.ObjectInstance as DataSets.TestsDBTableAdapters.QueriesTableAdapter;
qAda.CommandTimeout = 480;
}