[SOLVED] 500 – The request timed out

Issue

I have a script that runs for about 4mins30seconds and I have changed the default timeout time to 3600 seconds in the config page of my aspx webpage

It didn’t return the 500 – The request timed out error on the development version and the uploaded version on IIS 8.

However when I uploaded it to the live site at azure, it returns the 500 – The request timed out error.

Does Azure overwrites these settings?

Configs:

<configuration>
  <system.web>
    <httpRuntime executionTimeout="3600" />
    <sessionState timeout="360" />
    <compilation debug="false" targetFramework="4.0">
      <assemblies>
        <add assembly="System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
        <add assembly="System.Web.Extensions.Design, Version=4.0.0.0, Culture=neutral/>
      </assemblies>
    </compilation>
  </system.web>
</configuration>

EDIT:

I added SCM_COMMAND_IDLE_TIMEOUT into azure application settings with 3600 value but it didn’t fix the error, trying to improve my code’s performance now:

Original:

Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();

Dictionary<int, Dictionary<DateTime, float>> d_PhoneNo_DateDataList = new Dictionary<int, Dictionary<DateTime, float>>();

string sqlcommand = "SELECT ---- FROM ---- INNER JOIN ---- ON ---- = ---- WHERE [email protected] AND date BETWEEN @Date1 AND @Date2";
string strConnectionString = ConfigurationManager.ConnectionStrings["---"].ConnectionString;

using (SqlConnection conn = new SqlConnection(strConnectionString))
{
    Dictionary<DateTime, float> d_DateTime_Data;

    using (SqlCommand cmd = new SqlCommand(sqlcommand, conn))
    {
        cmd.Parameters.Add("@PhoneNo", SqlDbType.Int);
        cmd.Parameters.AddWithValue("@Date1", dateStart);
        cmd.Parameters.AddWithValue("@Date2", dateEnd.AddDays(1));
        conn.Open();

        for (int i = 0; i < phoneNo.Count; i++)
        {
            d_DateTime_Data = new Dictionary<DateTime, float>();
            cmd.Parameters["@PhoneNo"].Value = phoneNo[i];
            cmd.ExecuteNonQuery();
            using (SqlDataReader reader = cmd.ExecuteReader())
            {
                while (reader.Read())
                {
                    d_DateTime_Data.Add(DateTime.Parse(reader["Date"].ToString()), float.Parse(reader["Data"].ToString()));
                }
            }
            d_PhoneNo_DateDataList.Add(phoneNo[i], d_DateTime_Data);
        }
        conn.Close();
    }
}

I tried to use a concurrentDictionary with Parallel.For but it creates issues with the DataReader

ConcurrentDictionary<int, Dictionary<DateTime, float>> d_PhoneNo_DateDataList = new ConcurrentDictionary<int, Dictionary<DateTime, float>>();

string sqlcommand = "SELECT ---- FROM ---- INNER JOIN ---- ON ---- = ---- WHERE [email protected] AND date BETWEEN @Date1 AND @Date2";
string strConnectionString = ConfigurationManager.ConnectionStrings["----"].ConnectionString;

using (SqlConnection conn = new SqlConnection(strConnectionString))
{
    Dictionary<DateTime, float> d_DateTime_Data;

    using (SqlCommand cmd = new SqlCommand(sqlcommand, conn))
    {
        cmd.Parameters.Add("@PhoneNo", SqlDbType.Int);
        cmd.Parameters.AddWithValue("@Date1", dateStart);
        cmd.Parameters.AddWithValue("@Date2", dateEnd.AddDays(1));
        conn.Open();

        Parallel.For(0, phoneNo.Count, (index) =>
        {
            d_DateTime_Data = new Dictionary<DateTime, float>();
            cmd.Parameters["@PhoneNo"].Value = phoneNo[index];
            cmd.ExecuteNonQuery();
            using (SqlDataReader reader = cmd.ExecuteReader())
            {
                while (reader.Read())
                {
                    d_DateTime_Data.Add(DateTime.Parse(reader["Date"].ToString()), float.Parse(reader["Data"].ToString()));
                }
            }
            d_PhoneNo_DateDataList.TryAdd(phoneNo[index], d_DateTime_Data);
        });
        conn.Close();
    }
}

Solution

If your web app has any piece of code that takes this long time then move it to a web job instead, at least to avoid any impact on the application scalability.

  1. Create a web job and move the code that takes a long time to it.

  2. Make the web job listen for a queue

  3. In your web app, after the user submit, insert a message with the required details in the queue

  4. If you need to notify the user about the completion of the process, then use SignalR, connect to the hub from your JavaScript, and post a message top it from the web job code, this will notify the user immediately

Answered By – Haitham Shaddad

Answer Checked By – Timothy Miller (BugsFixing Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *