2012-04-19 148 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 2012-04-19 19:34:35

+0

@Jason;然後什麼? – BeemerGuy 2012-04-19 19:38:15

+1

如果這是整個網站崩潰,我至少會嘗試進食異常並將用戶發送到錯誤頁面以查看是否可以防止網站崩潰。然後我將重點放在潛在的問題上。 – Jason 2012-04-19 19:46:05

回答

1

問題是我有一個嘗試finally代碼塊。在處理的異常中,相關的finally塊將保證運行。但是,如果異常未處理,finally塊的執行取決於如何觸發異常展開操作。這反過來又取決於你的電腦設置方式。

爲了確保finally塊每次不能省略catch塊時都執行。 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。儘快關閉它們,然後依次進行數據訪問。這應該解決這個問題。