Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

500 - The request timed out

Tags:

c#

asp.net

azure

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 PhoneNo=@PhoneNo 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 PhoneNo=@PhoneNo 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();
    }
}
like image 796
Bloopie Bloops Avatar asked Dec 12 '16 05:12

Bloopie Bloops


2 Answers

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

like image 116
Haitham Shaddad Avatar answered Sep 23 '22 15:09

Haitham Shaddad


You are most probably running into the 230-second timeout hardcoded in App Service.

See this question for more:
Azure ASP .net WebApp The request timed out

Try to have that long running task as a WebJob and post the results to a Queue or Table. Or post to a Table/Blob (maybe even Redis if you're reusing the data a lot) and signal with a Queue message.

like image 42
evilSnobu Avatar answered Sep 22 '22 15:09

evilSnobu