首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> 關於ASP.NET

巧用 .NET Reflection 從 SqlConnection 回溯到開啟著的 SqlDataReader

     編輯:關於ASP.NET

經典異常:There is already an open DataReader...

原因:單一 SqlConnection 同一時間只能關聯一個開啟的 SqlDataReader。忘記關閉第一個 Reader 再嘗試開啟第二個即拋出此異常。

重現代碼

SqlConnection conn = new SqlConnection(connStr);
conn.Open();
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT * FROM Person";
SqlDataReader reader1 = cmd.ExecuteReader();
while (reader1.Read()) { /* ... */ }
// 忘記 reader1.Close()

cmd.CommandText = "SELECT * FROM Course";
SqlDataReader reader2 = cmd.ExecuteReader(); // 拋出異常
while (reader2.Read()) { /* ... */ }

實務困境:封裝後難以定位「忘關的 Reader」

實際專案中代碼層層封裝,異常拋出時難以知道是哪個 Reader 未關閉。

反射回溯法:利用 Internal 成員

SqlConnection 無公開 API 取得當前開啟的 Reader,但內部成員可助一臂之力:

  • SqlConnection.GetOpenConnection() → SqlInternalConnection
  • SqlInternalConnection.FindLiveReader(SqlCommand command) → SqlDataReader
  • SqlDataReader.Command → 關聯的 SqlCommand

透過 Reflection 呼叫上述 Internal 方法/屬性,即可在捕捉異常時找出「正在佔用連線的 Reader」並記錄其堆疊資訊,快速定位 Bug。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved