2012-04-19 5 views
0

개발 한 응용 프로그램이 일주일에 약 2 회 완전히 충돌합니다. 충돌이 발생하면 응용 프로그램 풀이 재활용 될 때까지 전체 응용 프로그램이 종료됩니다. 개발 환경에서 오류를 재현 할 수 없습니다.ASP.NET 응용 프로그램 - 디버깅 수행 할 단계

아래에서 응용 프로그램 이벤트 뷰어의 충돌 및 오류 메시지를 일으키는 코드를 붙여 넣었습니다. 앱을 중단시키는 행은 ~~~~으로 시작합니다. 메시지에는 열려있는 DataReader가 있지만 코드를 검사했으며 항상 데이터 판독기와 연결을 닫습니다.

이 버그를 해결하기 위해 어떤 단계를 거쳐야하는지 알 수 없습니다. 어떤 도움이라도 대단히 감사하겠습니다. 고맙습니다!

public bool open() { 
     //-- check if connection is closed 
     if (this.dbconn.State == System.Data.ConnectionState.Closed) { 
      try { 
       this.dbconn.Open(); 
      } 
      catch (Exception ex) { 
       this.errorCode = (int)DatabaseErrorType.DBOpenFailed; 
       this.errorMessage = System.Web.HttpUtility.HtmlEncode(ex.Message); 
       throw ex; 
      } 
     } 
     return true; 
    } 

/// <summary> closes connection object</summary> 
    public bool close() { 
     if (!(this.dbconn == null)) { 
      if (!(this.dbconn.State == System.Data.ConnectionState.Closed)) { 
       try { 
        this.dbconn.Close(); 
       } 
       catch (Exception ex) { 
        this.errorCode = (int)DatabaseErrorType.DBCloseFailed; 
        this.errorMessage = System.Web.HttpUtility.HtmlEncode(ex.Message); 
        return false; 
       } 

      } 
     } 
     return true; 
    } 
     // GET MULTI Accounts 
    public List<DTO.DTOAccount> GetAccounts(DTO.DTOAccount objAcc) { 
     //-- reset error variables 
     resetError(); 

     // make sure the connection is open 
     if (this.open()) { 

      SqlDataReader sqlReader = null; 

      try { 

       SqlCommand sqlProcedure = new SqlCommand("[dbo].[sp_Select_ONECARD_ACCOUNTS]", this.dbconn); 
       sqlProcedure.CommandType = System.Data.CommandType.StoredProcedure; 
       sqlProcedure.Parameters.Add(new SqlParameter("@ACCOUNT"    , objAcc.AccountId)); 
       sqlProcedure.Parameters.Add(new SqlParameter("@UDEF_4"    , objAcc.UDEF_4)); 

       ~~~~sqlReader = sqlProcedure.ExecuteReader(); 

       List<DTO.DTOAccount> Accounts = new List<DTO.DTOAccount>(); 
       // iterate through all values returned 
       while (sqlReader.Read()) { 
        DTO.DTOAccount tmpAccount    = new ca.eyecode.onecard.DTO.DTOAccount(); 
        tmpAccount.AccountId     = (String)sqlReader["ACCOUNT"]; 
        tmpAccount.Category      = (String)sqlReader["CATEGORY"]; 
        tmpAccount.Groups      = (String)sqlReader["GROUPS"]; 
        tmpAccount.Suffix      = (String)sqlReader["SUFFIX"]; 
        tmpAccount.UDEF_1      = ((String)sqlReader["UDEF_1"]).Trim(); 
        tmpAccount.UDEF_4      = ((String)sqlReader["UDEF_4"]).Trim(); 
        tmpAccount.FirstName     = ((String)sqlReader["FNAME"]).Trim(); 
        tmpAccount.LastName      = ((String)sqlReader["LNAME"]).Trim(); 
        tmpAccount.Picture      = (sqlReader["PICTURE"] == DBNull.Value ? String.Empty : (String)sqlReader["PICTURE"]).Trim(); 
        // add account items 
        tmpAccount.AccountItems.Add (new DTO.DTOAccountItem() { Account= AccountType.ONEcardCash, Balance= Convert.ToDouble((Decimal)sqlReader["BALANCE_1"])}); 
        tmpAccount.AccountItems.Add (new DTO.DTOAccountItem() { Account= AccountType.Department, Balance= Convert.ToDouble((Decimal)sqlReader["BALANCE_2"])}); 
        tmpAccount.AccountItems.Add (new DTO.DTOAccountItem() { Account= AccountType.BookStore, Balance= Convert.ToDouble((Decimal)sqlReader["BALANCE_3"])}); 
        tmpAccount.AccountItems.Add (new DTO.DTOAccountItem() { Account= AccountType.TechBalance, Balance= Convert.ToDouble((Decimal)sqlReader["BALANCE_4"])}); 
        tmpAccount.AccountItems.Add (new DTO.DTOAccountItem() { Account= AccountType.Bonus1, Balance= Convert.ToDouble((Decimal)sqlReader["BALANCE_5"])}); 
        tmpAccount.AccountItems.Add (new DTO.DTOAccountItem() { Account= AccountType.MealPlanExtra, Balance= Convert.ToDouble((Decimal)sqlReader["BALANCE_6"])}); 
        tmpAccount.AccountItems.Add (new DTO.DTOAccountItem() { Account= AccountType.MealPlanDollars, Balance= Convert.ToDouble((Decimal)sqlReader["BALANCE_7"])}); 
        tmpAccount.AccountItems.Add (new DTO.DTOAccountItem() { Account= AccountType.AramarkCredit, Balance= Convert.ToDouble((Decimal)sqlReader["BALANCE_8"])}); 
        tmpAccount.AccountItems.Add (new DTO.DTOAccountItem() { Account= AccountType.AramarkEmployees, Balance= Convert.ToDouble((Decimal)sqlReader["BALANCE_9"])}); 
        // Combine Totals to One Meal PLAN 
        tmpAccount.AccountItems[5].Balance += tmpAccount.AccountItems[6].Balance; 
        tmpAccount.AccountItems[5].Balance += tmpAccount.AccountItems[8].Balance; 
        tmpAccount.AccountItems[6].Balance = 0; 
        tmpAccount.AccountItems[8].Balance = 0; 

        Accounts.Add(tmpAccount); 
       } 
       return Accounts; 
      } 
      finally { 
       try { 
       if (sqlReader != null) { 
        sqlReader.Close(); 
       } 
       } 
       catch {} 
       this.close(); 
      } 

     } 
     return null; 
    } 

ERROR

Event code: 3005 
Event message: An unhandled exception has occurred. 
Event time: 4/19/2012 11:30:39 AM 
Event time (UTC): 4/19/2012 5:30:39 PM 
Event ID: 7715c17b872240829c3dfb562268998e 
Event sequence: 1253 
Event occurrence: 1 
Event detail code: 0 

Application information: 
    Application domain: /LM/W3SVC/997719702/Root-1-129793277036652335 
    Trust level: Full 
    Application Virtual Path:/
    Application Path: 
    Machine name: 

Process information: 
    Process ID: 820 
    Process name: w3wp.exe 
    Account name: 

Exception information: 
    Exception type: InvalidOperationException 
    Exception message: There is already an open DataReader associated with this Command which must be closed first. 
    at System.Data.SqlClient.SqlInternalConnectionTds.ValidateConnectionForExecute(SqlCommand command) 
    at System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async) 
    at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) 
    at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) 
    at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) 
    at System.Data.SqlClient.SqlCommand.ExecuteReader() 
    at ca.eyecode.onecard.DAO.DAOAccount.GetAccounts(DTOAccount objAcc) in C:\inetpub\wwwroot\ONEcard\OneAccount\OneAccount\Models\ca.eyecode\onecard\DAO\DAOAccount.cs:line 47 
    at ca.eyecode.onecard.BL.BLAccount.AccountsGet(DTOAccount objAcc) in C:\inetpub\wwwroot\ONEcard\OneAccount\OneAccount\Models\ca.eyecode\onecard\BL\BLAccount.cs:line 228 
    at ca.eyecode.onecard.BL.BLAccount.AccountLogin(String CCID, String Password) in C:\inetpub\wwwroot\ONEcard\OneAccount\OneAccount\Models\ca.eyecode\onecard\BL\BLAccount.cs:line 171 
    at ca.eyecode.onecard.BL.BLFacade.AccountLogin(String CCID, String Password) in C:\inetpub\wwwroot\ONEcard\OneAccount\OneAccount\Models\ca.eyecode\onecard\BL\BLFacade.cs:line 36 
    at ca.eyecode.onecard.Controllers.HomeController.Index(String inpCCID, String inpPASS) in C:\inetpub\wwwroot\ONEcard\OneAccount\OneAccount\Controllers\HomeController.cs:line 77 
    at lambda_method(Closure , ControllerBase , Object[]) 
    at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) 
    at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) 
    at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassd.<InvokeActionMethodWithFilters>b__a() 
    at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) 
    at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) 
    at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) 
    at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) 
    at System.Web.Mvc.Controller.ExecuteCore() 
    at System.Web.Mvc.MvcHandler.<>c__DisplayClass8.<BeginProcessRequest>b__4() 
    at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass1.<MakeVoidDelegate>b__0() 
    at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 
    at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) 



Request information: 
    Request URL: 
    Request path:/
    User host address: 
    User: 
    Is authenticated: False 
    Authentication Type: 
    Thread account name: 

Thread information: 
    Thread ID: 9 
    Thread account name: 
    Is impersonating: False 
    Stack trace: at System.Data.SqlClient.SqlInternalConnectionTds.ValidateConnectionForExecute(SqlCommand command) 
    at System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async) 
    at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) 
    at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) 
    at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) 
    at System.Data.SqlClient.SqlCommand.ExecuteReader() 
    at ca.eyecode.onecard.DAO.DAOAccount.GetAccounts(DTOAccount objAcc) in C:\inetpub\wwwroot\ONEcard\OneAccount\OneAccount\Models\ca.eyecode\onecard\DAO\DAOAccount.cs:line 47 
    at ca.eyecode.onecard.BL.BLAccount.AccountsGet(DTOAccount objAcc) in C:\inetpub\wwwroot\ONEcard\OneAccount\OneAccount\Models\ca.eyecode\onecard\BL\BLAccount.cs:line 228 
    at ca.eyecode.onecard.BL.BLAccount.AccountLogin(String CCID, String Password) in C:\inetpub\wwwroot\ONEcard\OneAccount\OneAccount\Models\ca.eyecode\onecard\BL\BLAccount.cs:line 171 
    at ca.eyecode.onecard.BL.BLFacade.AccountLogin(String CCID, String Password) in C:\inetpub\wwwroot\ONEcard\OneAccount\OneAccount\Models\ca.eyecode\onecard\BL\BLFacade.cs:line 36 
    at ca.eyecode.onecard.Controllers.HomeController.Index(String inpCCID, String inpPASS) in C:\inetpub\wwwroot\ONEcard\OneAccount\OneAccount\Controllers\HomeController.cs:line 77 
    at lambda_method(Closure , ControllerBase , Object[]) 
    at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) 
    at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) 
    at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassd.<InvokeActionMethodWithFilters>b__a() 
    at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) 
    at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) 
    at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) 
    at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) 
    at System.Web.Mvc.Controller.ExecuteCore() 
    at System.Web.Mvc.MvcHandler.<>c__DisplayClass8.<BeginProcessRequest>b__4() 
    at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass1.<MakeVoidDelegate>b__0() 
    at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 
    at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) 
+0

왜 예외가 발생하지 않습니까? – Jason

+0

@Jason; 그 다음엔? – BeemerGuy

+1

이것이 전체 사이트를 손상시키는 경우 적어도 예외를 먹어보고 사용자에게 오류 페이지를 보내 사이트 충돌을 방지하는지 확인하려고합니다. 그렇다면 근본적인 문제에 집중할 것입니다. – Jason

답변

1

문제는 내가 코드에서 finally 블록을 시도했기 때문입니다. 처리 된 예외 내에서 연관된 finally 블록이 실행되도록 보장됩니다. 그러나 예외가 처리되지 않은 경우 finally 블록의 실행은 예외 해제 작업이 트리거되는 방법에 따라 다릅니다. 이는 차례로 컴퓨터 설정 방법에 달려 있습니다.

catch 블록을 생략 할 수 없을 때마다 finally 블록이 실행되는지 확인하십시오. http://msdn.microsoft.com/en-us/library/zwc8s4fz(v=vs.100).aspx

0

당신이 정말로 그때처럼 뭔가 방법을 리팩토링 것 다른 곳에서 연결 개체를 필요로하지 않는 :

public List<DTO.DTOAccount> GetAccounts(DTO.DTOAccount objAcc) 
{ 
    //-- reset error variables 
    resetError(); 

    List<DTO.DTOAccount> Accounts = new List<DTO.DTOAccount>(); 

    try 
    { 
     using (SqlConnection dbconn = new SqlConnection("your-connection-string")) 
     { 
      using (SqlCommand sqlProcedure = new SqlCommand("[dbo].[sp_Select_ONECARD_ACCOUNTS]", dbconn)) 
      { 
       sqlProcedure.CommandType = System.Data.CommandType.StoredProcedure; 
       sqlProcedure.Parameters.Add(new SqlParameter("@ACCOUNT", objAcc.AccountId)); 
       sqlProcedure.Parameters.Add(new SqlParameter("@UDEF_4", objAcc.UDEF_4)); 
       dbconn.Open(); 
       using (SqlDataReader sqlReader = sqlProcedure.ExecuteReader()) 
       { 
        while (sqlReader.Read()) 
        { 
         DTO.DTOAccount tmpAccount = new ca.eyecode.onecard.DTO.DTOAccount(); 
         tmpAccount.AccountId = (String)sqlReader["ACCOUNT"]; 
         tmpAccount.Category = (String)sqlReader["CATEGORY"]; 
         tmpAccount.Groups = (String)sqlReader["GROUPS"]; 
         tmpAccount.Suffix = (String)sqlReader["SUFFIX"]; 
         tmpAccount.UDEF_1 = ((String)sqlReader["UDEF_1"]).Trim(); 
         tmpAccount.UDEF_4 = ((String)sqlReader["UDEF_4"]).Trim(); 
         tmpAccount.FirstName = ((String)sqlReader["FNAME"]).Trim(); 
         tmpAccount.LastName = ((String)sqlReader["LNAME"]).Trim(); 
         tmpAccount.Picture = (sqlReader["PICTURE"] == DBNull.Value ? String.Empty : (String)sqlReader["PICTURE"]).Trim(); 
         // add account items 
         tmpAccount.AccountItems.Add(new DTO.DTOAccountItem() { Account = AccountType.ONEcardCash, Balance = Convert.ToDouble((Decimal)sqlReader["BALANCE_1"]) }); 
         tmpAccount.AccountItems.Add(new DTO.DTOAccountItem() { Account = AccountType.Department, Balance = Convert.ToDouble((Decimal)sqlReader["BALANCE_2"]) }); 
         tmpAccount.AccountItems.Add(new DTO.DTOAccountItem() { Account = AccountType.BookStore, Balance = Convert.ToDouble((Decimal)sqlReader["BALANCE_3"]) }); 
         tmpAccount.AccountItems.Add(new DTO.DTOAccountItem() { Account = AccountType.TechBalance, Balance = Convert.ToDouble((Decimal)sqlReader["BALANCE_4"]) }); 
         tmpAccount.AccountItems.Add(new DTO.DTOAccountItem() { Account = AccountType.Bonus1, Balance = Convert.ToDouble((Decimal)sqlReader["BALANCE_5"]) }); 
         tmpAccount.AccountItems.Add(new DTO.DTOAccountItem() { Account = AccountType.MealPlanExtra, Balance = Convert.ToDouble((Decimal)sqlReader["BALANCE_6"]) }); 
         tmpAccount.AccountItems.Add(new DTO.DTOAccountItem() { Account = AccountType.MealPlanDollars, Balance = Convert.ToDouble((Decimal)sqlReader["BALANCE_7"]) }); 
         tmpAccount.AccountItems.Add(new DTO.DTOAccountItem() { Account = AccountType.AramarkCredit, Balance = Convert.ToDouble((Decimal)sqlReader["BALANCE_8"]) }); 
         tmpAccount.AccountItems.Add(new DTO.DTOAccountItem() { Account = AccountType.AramarkEmployees, Balance = Convert.ToDouble((Decimal)sqlReader["BALANCE_9"]) }); 
         // Combine Totals to One Meal PLAN 
         tmpAccount.AccountItems[5].Balance += tmpAccount.AccountItems[6].Balance; 
         tmpAccount.AccountItems[5].Balance += tmpAccount.AccountItems[8].Balance; 
         tmpAccount.AccountItems[6].Balance = 0; 
         tmpAccount.AccountItems[8].Balance = 0; 

         Accounts.Add(tmpAccount); 
        } 
       } 
      } 
     } 
    } 
    catch 
    { 
     // do some error handling. 
    } 

    return Accounts; 
} 
1

확실히, 당신은 그냥 사용할 수 있습니다 SqlDataReader 주위의 using 성명 다른 요소들도 똑같이하십시오. 그렇게하면 항상 처분되고 폐쇄됩니다.

그 다음으로는 SqlDataReaders를 중첩하지 않도록하십시오. 가능한 한 빨리 닫고 데이터 액세스를 순차적으로 수행하십시오. 그게 문제를 해결해야합니다.