Using block

在改寫某支程式 (Windows form,3-tired) 時,無意間發現,Using / End Using 並不完全適用於任何情況下,尤其當有元件間物件轉移的時候。

Using / End Using 的執行權優於 conn.close : conn = nothing。

component.dll 中的某一段:

'功能說明:由 學生姓名 取得其基本資料
Public Shared Function QueryData(ByVal Name As String) As SqlDataReader
Dim strConn As String = My.Settings.Conn
Dim connQueryData As SqlConnection = New SqlConnection(strConn)
Dim cmdQueryData As SqlCommand = New SqlCommand()
Dim drQueryData As SqlDataReader

Try
cmdQueryData.CommandType = CommandType.StoredProcedure
cmdQueryData.CommandText = "TheStoredProcedure"
cmdQueryData.Parameters.AddWithValue("@Name", Name)
cmdQueryData.Connection = connQueryData
connQueryData.Open()

drQueryData = cmdQueryData.ExecuteReader

If drQueryData.Read Then
Return drQueryData
Else
Return Nothing
End If

connQueryData.Close() : connQueryData = Nothing

Catch ex As SqlException
Return Nothing
End Try
End Function


由主程式呼叫時,若 sample code 中 的 conn.close : conn = nothing 以 Using conn / End Using 的方式表達,那麼在執行時,將會收到 Metadata 已關閉的訊息。這表示了,Using conn / End Using Block 將於呼叫完成時便馬上關閉 conn,而造成主程式收的到 Return obj 已遭關閉而無法順利讀取實值的窘境。

雖然使用 Using Block 是好的習慣,但在某一些情況下使用它,卻反而會收到反效果。

1 留言

Unknown寫道…
後來又再回來看這篇,哈哈哈,我犯了嚴重的錯誤吶XD
1. Return 的物件為 SqlDataReader 時,必須持續保持連線狀態。
2. 加在 return Obj 後的 connQueryData.Close() : connQueryData = Nothing 其實跟不會有動件,冏

真是怪了,當時的我是在想啥小啊,大概是裝了太多大便在腦袋裡了@_@