Время ожидания запроса истекло

Раз за разом я сталкиваюсь со следующей проблемой и не знаю как ее исправить..

Я часто получаю следующие ошибки, и мне пришлось restart the IIS или же republish чтобы решить проблему временно:

Error Message:Request timed out.
Error Message:ERROR [08S01] [Informix .NET provider]Communication link failure.
Error Message:Thread was being aborted.

Я пытаюсь сделать:

<httpRuntime executionTimeout="600" />

но все те же проблемы!!


Stack Trace:
   at System.Web.HttpContext.InvokeCancellableCallback(WaitCallback callback, Object state)
   at System.Web.UI.Page.AsyncPageBeginProcessRequest(HttpContext context, AsyncCallback callback, Object extraData)
   at ASP.appmaster_aspx.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object data)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Мой PageLoad:

 protected void Page_Load(object sender, EventArgs e)
        {


            if (Session["emp_num"] != null && !string.IsNullOrEmpty(Session["emp_num"].ToString()))
            {
                try
                {

                    string user_setting = Personalization_DAL.CheckWidgetSettings(int.Parse(Session["emp_num"].ToString()));

                    if (!string.IsNullOrEmpty(user_setting))
                    {
                        user_flag = int.Parse(user_setting);
                    }

                    GetLinkedApp = DB_Connection_s.DB_Connection.GetLinkedAppUser(int.Parse(Session["emp_num"].ToString()));
                    if (!Page.IsPostBack)
                    {
                        //Profile
                        GetProfile();

                        if (Session["emp_app"] != null && !string.IsNullOrEmpty(Session["emp_app"].ToString()))
                        {
                            BindAvailableSystems(Session["emp_app"].ToString());
                        }

                        BindMainSystems();

                        if (GetLinkedApp > 0)
                        {
                            rlv_available_sys.Visible = true;
                            h5_app.Visible = true;
                            lbtn_addApp.Visible = false;
                            h4_app.Visible = false;
                            intro.Visible = true;

                        }
                        else
                        {
                            rlv_available_sys.Visible = false;
                            h5_app.Visible = false;
                            lbtn_addApp.Visible = true;
                            h4_app.Visible = true;
                            intro.Visible = false;
                        }
                        //Applications
                        if (rlv_available_sys.Visible == true)
                        {
                            Session["emp_app"] = GetLinkedApp;
                            BindAvailableSystems(Session["emp_app"].ToString());
                            if (user_flag > 0)
                            {
                                Get_UserApplicationSystems(1, 1, GetLinkedApp.ToString());
                            }
                            else
                            {
                                Get_UserApplicationSystems(user_flag, 1, GetLinkedApp.ToString());
                            }

                        }
                        //services
                        Get_MainSystems(user_flag);
                        if (GetLinkedApp > 0)
                        {
                            GetServiceInformation();
                        }
                        string[] statistics = TrackUser();
                        base.TraceActivity("Enter the portal", "https://" + Request.Url.Authority + "/AppMaster.aspx", statistics[0], statistics[1], statistics[2]);
                    }

                    TraceSystemsMode();
                }
                catch (Exception ee)
                {
                    string message = ee.Message;
                }

            }
            else
            {
                Response.Redirect("LoginPage.aspx", false);
            }
        }

Мой универсальный обработчик:

public void ProcessRequest(HttpContext context)
        {
            try
            {
                using(Stream photo_stream = Photo_DAL.RetrievePhoto(int.Parse(context.Session["emp_num"].ToString())))
               {
                byte[] photo_bytes = Photo_DAL.StreamToByteArray(photo_stream);
                if (photo_bytes == null)
                {
                    photo_bytes = File.ReadAllBytes(Path.Combine(context.Server.MapPath("~/images/PortalImages/"), "user.png"));
                }
                //context.Response.ContentType = "image/png";
                context.Response.BinaryWrite(photo_bytes);
                }
            }
            catch (Exception ee)
            {
            }

        }

4 ответа

Решение

Это предположение, поскольку существует много ссылочного кода, который мы не видим из этого фрагмента, размещенного в вопросе.

Я предполагаю, что вы неправильно обрабатываете соединения с базой данных (DB_Connection_s) по нескольким причинам.

А) Исправлено через сброс

    I get the following errors frequently , and i had to restart the IIS or 
    republish to fix the problem temporary`

Для меня это означает, что вы используете все соединения с вашей базой данных, потому что при перезапуске или повторной публикации все текущие соединения сбрасываются.

Б) Нет четкой утилизации

В вашем коде вы ссылаетесь DB_Connection_sоднако он не заключен в блок using и не создается, что означает, что он, скорее всего, является статическим классом или методом (трудно сказать без кода для этой ссылки).

Предложение

Убедитесь, что вы всегда правильно утилизируете соединения с базой данных. Они ДОЛЖНЫ иметь.Dispose(), вызванный на них, когда закончено. Обычно это достигается путем взятия класса, который содержит контекст, и его реализации IDisposableа затем обернутьвсе ваши звонки в этот класс с помощью оператора using. Использование оператора вызовет Disposeметод автоматически. Если вы предпочитаете не реализовыватьIDisposable Вы также можете явно (не рекомендуется) избавиться от соединения с базой данных, когда закончите с ним, позвонив .Dispose() непосредственно на соединение после завершения запроса.

Редактировать в ответ на вновь добавленные комментарии:

@just_name - из кода здесь в комментариях, мне кажется, что может быть проблема. Надеется~DBConnection()распоряжаться вашей связью, только звоня.Close()и не закрывая поток, это то, что выделяется для меня.

я) Финализаторы могут занять много времени

Использование финализатора для удаления соединения может быть рискованным, потому что вы никогда не можете быть точно уверены, когда оно вызывается. "Точное время выполнения финализатора во время сборки мусора не определено". - MSDN Object.Finalize. Это может привести к тому, что система будет ждать очень долго, если у нее будет много ресурсов, прежде чем какие-либо подключения будут ликвидированы, что приведет к замедлению запросов.

II) Закрыть не утилизировать

Хотя вы технически безопасно звоните.Close()на соединении, это может вызвать проблемы в производстве. Причина в том, что соединение будет закрыто, но обработчики событий останутся, и иногда, если происходит ленивая загрузка или динамические прокси-серверы, эти обработчики событий могут хранить копии соединения.

iii) использовать утилизировать

а) Удалите вашу связь явно

Всегда явно распоряжайтесь своим подключением, не ждите, пока сборщик мусора сделает это. Лучший способ избавиться от него - использоватьusing(){}блокировать при доступе к вашемуDBConnectionучебный класс. Вы можете сделать несколько изменений, чтобы сделать это:

Определите DBConnection для реализации IDisposable, чтобы его можно было использовать в блоке using

public class DBConnection : IDisposable
{
  //other methods already in here
  public void Dispose()
  {
   //Close_Connection(); Call this if you want, but you MUST call 
   //.Dispose on your connections
   connection.Dispose();
  }
}

Это позволит вам создать новый DBConnection следующим образом:

using( var DB_Connection_s = new DBConnection() )
{
 //todo: interact with database connection
}

Блок using будет автоматически вызывать.Dispose()когда финал}достигнут и избавиться от соединения гарантировано. Кроме того, это позволяет сократить время транзакции с базой данных, что может увеличить скорость запросов и запросов, если для доступа к базе данных были задействованы какие-либо очереди.

Если вам не нравится реализация блока using, по крайней мере, измените.Close()в.Dispose()везде, где вы используете close и убедитесь, что нет возможного пути исполнения, который ведет к .Dispose() не вызывается сразу после завершения доступа к базе данных.

б) использовать.Dispose()на неуправляемых ресурсах

Всегда используйте .Dispose() на неуправляемых ресурсах. Есть несколько способов сделать это, но лучший способ - using(){} блок. Я заметил, что вы можете реализовать это в одном месте специально с потоком в вашем коде, который должен быть обработан.

Это один из оскорбительных фрагментов кода:

IfxDataReader ifxDataReaders = DB_Connection.DBCmd.ExecuteReader(); 
if (ifxDataReaders.Read()) { 
 item = (int)ifxDataReaders["emp_num"]; 
} 
ifxDataReaders.Close();

Я возьму пару вопросов с этим. Во-первых, вы звоните .Close() который обсуждался выше. Во-вторых, поскольку это находится в блоке try, возможно, что ifxDataReaders может выдать исключение, и программа продолжит работу, даже не закрывая и не удаляя устройство чтения. Это может вызвать много проблем.

Что вы должны сделать, это убедиться, что .Dispose всегда вызывается на ваших неуправляемых ресурсах. Вы можете сделать это с использованием блока (который неявно всегда вызывает .Dispose()).

using(IfxDataReader ifxDataReaders = DB_Connection.DBCmd.ExecuteReader())
{
 if (ifxDataReaders.Read()) { 
  item = (int)ifxDataReaders["emp_num"]; 
 } 
}

Главный вопрос: почему это так долго? Почему какой-то переход на страницу занимает более 30 секунд? Можете ли вы действительно жить с таким медленным сайтом?

Мы должны увидеть, как снизить производительность, чтобы запрос завершился в течение 30 секунд.

Можете поделиться кодом? Давайте посмотрим, где узкое место в коде.

Я знаю, что это не относится к Error Message:Request timed out но может иметь связь с Error Message:Thread was being aborted., Итак, поскольку у нас нет примера кода, я думаю, что можно думать, что это может быть Response.Redirect("aPage.aspx") проблемы, когда он сделан внутри блока Try-Catch.

Если это ваш случай, попробуйте добавить "False" в параметр EndResponse Response.Redirect метод, как показано здесь:

try {
    // [... SOME CODE ...]
    Response.Redirect("aPage.aspx", False)
} catch (Exception e) {
    // [... YOUR CATCH ...]
}

Так что я проголосовал за комментарий от Зии, предлагающий вам запускать части по отдельности, чтобы изолировать время ожидания. Есть ли вероятность, что это может быть ошибка с подключением Informix?

У запросов к базе данных есть два тайм-аута: тайм-аут соединения и тайм-аут команды. Ни один из них не будет использовать значение executeTimeout. Я не пытался использовать поставщик Informix, но я увеличил тайм-ауты для объекта подключения, если сервер занят или объект команды для ожидания выполнения длинного запроса SQL.

Вот ссылка на настройку connectionTimeout для объекта подключения Informix... http://publib.boulder.ibm.com/infocenter/idshelp/v115/index.jsp?topic=%2Fcom.ibm.net_cc.doc%2Fcom.ibm.swg.im.dbclient.adonet.ref.doc%2Fdoc%2FDB2ConnectionClassConnectionTimeoutProperty.htm

Другие вопросы по тегам