14

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();
    }
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
LuxuryWaffles
  • 1,518
  • 4
  • 27
  • 50
  • You get this error in browser? or you are calling this page from other place? – Vova Bilyachat Dec 12 '16 at 06:10
  • I got it in the browser, sort of like an error page – LuxuryWaffles Dec 12 '16 at 06:24
  • How is your application deployed? Is it running as a Web App or running inside a VM/Cloud Service? – Gaurav Mantri Dec 12 '16 at 09:04
  • @GauravMantri it's running as an web app – LuxuryWaffles Dec 12 '16 at 09:04
  • I tried to search for this issue and it seems that there's a default limit of 4 minutes in Azure Load Balancer. Any requests more than that will be timed out. I also read the possibility of changing this behaviour (https://azure.microsoft.com/en-us/blog/new-configurable-idle-timeout-for-azure-load-balancer/) but it only talks about VMs and Cloud Services. There are many other workarounds suggested (like request.KeepAlive = true). I suggest you search for "Azure Web App Request Timeout" and you will find many questions related to this issue. – Gaurav Mantri Dec 12 '16 at 09:13
  • ok thanks, will look into it – LuxuryWaffles Dec 12 '16 at 09:23

4 Answers4

12

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

shA.t
  • 16,580
  • 5
  • 54
  • 111
Haitham Shaddad
  • 4,336
  • 2
  • 14
  • 19
11

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.

Community
  • 1
  • 1
evilSnobu
  • 24,582
  • 8
  • 41
  • 71
1

We had the same issue with Azure when we were using an older version of the SDK (2.3) and a load balancer making webservice calls. This may not be the same for you because you are doing database query. The default timeout for the load balancer is 4 minutes. Updating to a newer version of the SDK and using the endpoint setting of idleTimeoutInMinutes allows up to 30 minutes max (I think) before timeout.

Action:

You are hosting a cloud service in Azure

Result:

You have clients that call into your cloud service, and if the cloud service call takes longer than 4 minutes then your clients were hanging until they got client side timeouts.

Cause:

The default idle timeout of TCP connections in the Azure Cloud Service Load Balancer is 4 minutes.

Resolution:

You would need to upgrade to at least the 2.4 Azure SDK and then you can enable the idleTimeoutInMinutes attribute of the CSDEF file to control how long the Azure Load Balancer lets these idle TCP connections to remain alive before resetting that connection.

<Endpoints>
  <InputEndpoint name="Endpoint1" protocol="http" port="80" idleTimeoutInMinutes="6" />
</Endpoints>

New: Configurable Idle Timeout for Azure Load Balancer http://azure.microsoft.com/blog/2014/08/14/new-configurable-idle-timeout-for-azure-load-balancer/

Brian from state farm
  • 2,825
  • 12
  • 17
0

if you are using Azure Web App and got this is error. It's due to the fact that by default timeout set for the web app on the load balance in azure is 230 second that is 3.8 minutes. If your app takes more then this time to respond to the request you get this error.

To troubleshoot the issue, please check if any logic processing take long time to complete and return response in your code.