This is the designed behaviour. CommandTimeout If server doesn't respond within the specified CommandTimeout period, an exception is thrown. When you execute the pg_sleep(), the server sleeps, and if it doesn't respond within the specified CommandTimeout period, the "Server did not respond within the specified timeout interval." exception occurs.
When you execute command.ExecuteReader(), you don't get this exception because the server responds on time. The application doesn't respond because it reads data to the memory, and the ExecuteReader() method doesn't return control until all the data is read.
If you want PgSqlDataReader to finish reading after some period of time, you may use the following workaround: execute the ExecuteReader() method with the CommandBehavior.SequentialAccess parameter. In this case, the data are not read to the memory buffer; instead a single row is read each time you call the Read method.
Code: Select all
static void Main(string[] args)
{
using (PgSqlConnection connection = new PgSqlConnection("your connection string"))
{
connection.Open();
PgSqlCommand command = connection.CreateCommand();
command.CommandText = "SELECT * FROM public.LargeTable";
connection.Open();
Stopwatch watch = new Stopwatch();
int count = 0;
TimeSpan timeout = new TimeSpan(0, 0, 10);
using (PgSqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
{
bool work = true;
while (work)
{
watch.Start();
work = reader.Read();
watch.Stop();
count++;
if (watch.Elapsed >= timeout)
{
Console.WriteLine("Timeout is reached. " +count+" rows are read");
break;
}
}
}
connection.Close();
}
}