I have some strange behavior occurring in an ASP.NET application that I am trying to fix.
I am getting the following error from code:
Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
I am familiar with this error and many of it’s causes. All of my typical avenues of trouble shooting have failed.
Here are some of the dynamics:
The server was recently re-built. So it could be a server configuration issue.
This error only happens on a specific web server. When I run the application it locally, and from other servers it is fast. I cannot re-pro perf issues with the proc in MSSMS from my machine.
- This tells me that it is specific to this server.
When I run The same proc using the OSql command–line utility It works. Fast.
- This indicates that it is likely something .NET related, NOT db related
Prior to this code executing, I have executed other Stored procedures on this server, and on this same DB.
- This suggests the proc may be related , but is not a “server X cannot talk to server Y”
I have gotten confirmation From DB owners that the DB has received the command, executed (>1second )it and returned the data.
- By tracing the code, I see the results are returned and it is not until I try to close the data reader that the error occurs.
- In fact I see it takes 36 milliseconds to execute the stored procedure and iterate through the result.
It looks like the call to DataReader.Close is what is taking time, and eventually timing out.
I have increased the max Pool from 31 to 100.
Here is a sample of what my code looks like, how it is structured. I have been hacking at it for trouble shooting: I have added the explict close to ensure I know where the error occurs. There may be syntax issues: I have made it generic, and may have introduced bugs in doing so.
public double GetMyData()
{
double returnValue;
// Used in logging to see if code was reached & how long it took.
System.Diagnostics.Stopwatch s = new System.Diagnostics.Stopwatch();
using (SqlConnection cn = Connections.GetSqlConnection())
{
cn.Open();
using (SqlCommand cmd = getSQLCommmand("SomeProcName"))
{
Log.Log.WriteTrace(string.Format("Execute {0} ","SomeProcName"),0);
s.Start();
SqlDataReader dr= null;
try
{
dr = cmd.ExecuteReader();
s.Stop();
Log.Log.WriteTrace("Timer", "ExecuteReader done " + s.ElapsedMilliseconds + "ms ", 0);
s.Start();
if (dr != null)
{
if (dr.Read())
{
returnValue =
Conversion.DBNullToDouble(
dr[0]);
}
s.Stop();
Log.Log.WriteTrace("Timer", "dr.read done (result:" + returnValue + ")" + s.ElapsedMilliseconds + "ms ", 0); // I get Here
}
}catch(Exception ex)
{
Log.Log.PersistException(ex);
}
//}
if(dr!=null && !dr.IsClosed)
dr.Close();// This times out
if (cn != null && cn.State !=ConnectionState.Closed)
cn.Close();
Log.Log.WriteTrace("DONE "),
;
}
}
return (returnValue);
}
UPDATE
dr.Close(); takes 2 minutes to execute. Just on this server. Locally it takes less than a second.
UPDATE
Per the accepted answer’s comments: I have a proc that has multiple records. I am taking the fist one. Calling cmd.Cancel() has not fixed, but has drastically reduced the time taken to close the data reader. Exploring this should help me fix the problem. I do not know why this is only happening on this server, as the server is a dev server.
I see few problems in your code.
You are closing 2 times the connection (when using
if (cn != null && cn.State !=ConnectionState.Closed)cn.Close();
and in the
using (SqlConnection cn = Connections.GetSqlConnection())— this one do it for you at the end of the statementIn your code you are not checking if the DataReader.HasRows So if your Sproc doesn’t return a value it will throw an exception in the
if (dr.Read())so that could be the reason that’s why you are getting sometimes the time out exceptionFinally
I would rewrite your code like this (using DataReader)
Or (with ExecuteScalar)