簡體   English   中英

內部異常C#

[英]Inner Exceptions C#

故事:我有3個不同班級的3個功能。 函數調用順序是:

Form1_Load(...) - > Student.GetAllStudents(...) - > StudentDAL.GetStudentInformation(...) - > ConnectionManager.GetConnection(...)

. 我想要做的是在MessageBox中顯示最內層函數的StackTrace,即ConnectionManager.GetConnection() 換句話說,我不想在任何內部類中使用MessageBox ,而只是在Form1類的外部類中

問題:為了獲得內部異常,我們可以使用InnerExceptionGetBaseException()等,但是當我嘗試獲取內部異常時,它會引發異常“對象引用未設置為實例”,這意味着沒有內部異常,當我檢查時,該值也為null 我想知道為什么它是null 它不應該持有對內部異常的引用嗎? 如果我錯了糾正我。

功能碼:

  1. Form1_Load(...)

     private void Form1_Load(object sender, EventArgs e) { try { DataTable dt = new DataTable(); dt.Load((**new Student().GetAllStudents()**)); if (dt.Rows.Count <= 0) { MessageBox.Show("Student table empty."); } else { this.dataGridView1.DataSource = dt; } } catch (Exception ex) { MessageBox.Show(ex.Message+Environment.NewLine+"Source(s) : "+ex.StackTrace.Substring(0, ex.StackTrace.LastIndexOf("at"))); } 
  2. GetAllStudents(...)

     public SqlDataReader GetAllStudents() { try { return StudentInformationDataAccessLayer.GetStudentInformation(); } catch (Exception ex) { throw ex; } } 
  3. GetStudentInformation(...)

     public static SqlDataReader GetStudentInformation() { try { SqlConnection sqlCon = null; sqlCon = ConnectionManager.GetConnection(); if (sqlCon == null) { return null; } String Query = null; Query = "SELECT * FROM [dbo].[Student]"; SqlCommand cmd = new SqlCommand(Query, sqlCon); SqlDataReader dr = null; dr = cmd.ExecuteReader(CommandBehavior.CloseConnection); return dr; } catch (Exception ex) { throw ex; } } 
  4. GetConnection(...)

     public static SqlConnection GetConnection() { String _connectionString = null; _connectionString = ConfigurationManager.ConnectionStrings["Default"].ConnectionString; if (_connectionString == null) { return null; } try { SqlConnection connection = new SqlConnection(_connectionString); connection.Open(); return connection; } catch (Exception ex) { throw ex; } } 

如果要保留堆棧跟蹤和異常信息,則應更改重新引發捕獲的異常的代碼,如下所示:

 }
 catch(Exception ex)
 {
     // do what you need to do with ex
     // ..
     // rethrow..

     throw;           // notice this is not "throw ex";
 }

使用just throw;重新拋出異常throw; 保留原始堆棧跟蹤。 不一定有內部異常,但這不是你應該關心的。 您需要知道的是異常發生的堆棧跟蹤。

如果你想重新拋出內部異常集,請使用下面的代碼,但請記住,你將丟失堆棧跟蹤

try
{
   ...
}
catch (Exception ex)
{
  throw new Exception("message", ex);
}

要重新拋出異常並保留堆棧跟蹤 ,請使用:

try
{
   ...
}
catch (Exception ex)
{
  throw;
}

並非每個異常都確實存在內部異常。 首先檢查內部ex是否為null ,如果不是則處理它。

說完這個,你當然可以重新拋出你的異常,如下所示:

catch(Exception ex)
 {
     // so smth
     // ..
     // rethrow..

     throw;          
 }

但請記住兩件事:

  1. 不要輸入throw ex ,只是throw

  2. 只有在重新拋出之前確實想要對此異常執行某些操作時才執行此操作。 如果你沒有這樣的計划,就不要在這個級別上抓住它。

我會做的事情如下:

try
{
  ...
}
catch (Exception ex)
{
  if (ex.InnerException == null)
    throw ex;
  else
    throw ex.InnerException;
}

然后在你想要進行堆棧跟蹤的某個點上,按照以下方式執行以下操作:

StackTrace trace = new StackTrace(System.Threading.Thread.CurrentThread, true);
StackFrame[] frames = trace.GetFrames();
string result = string.Empty;
foreach (StackFrame sf in frames)
{
  string += sf.GetMethod().Name;
}
MessageBox(result);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM