Code Snippet
- Dim SqlDataAdapter As New SqlClient.SqlDataAdapter
- Dim sqlCommand As New SqlClient.SqlCommand
- Dim dt_dataadapter As New DataSet
- 'Set Parameter
- With sqlCommand
- .Connection = dataConnection
- .CommandType = CommandType.StoredProcedure
- .CommandText = "blah blah"
- .Parameters.Add("@ID", SqlDbType.Int, 8, "ID").Value = 0
- End With
- SqlDataAdapter.SelectCommand = sqlCommand
- SqlDataAdapter.Fill(dt_dataadapter)
- If dt_dataadapter Is Nothing Then
- dt_dataadapter.Dispose()
- SqlDataAdapter.Dispose()
- sqlCommand.Dispose()
- MessageBox.Show("Failed retrieving 'blah blah'.")
- Exit Sub
- End If
- If dt_dataadapter.Tables.Count = 0 Then
- dt_dataadapter.Dispose()
- SqlDataAdapter.Dispose()
- sqlCommand.Dispose()
- MessageBox.Show("Failed retrieving 'blah blah'.")
- Exit Sub
- End If
- If dt_dataadapter.Tables(0).Rows.Count = 0 Then
- dt_dataadapter.Dispose()
- SqlDataAdapter.Dispose()
- sqlCommand.Dispose()
- MessageBox.Show("Failed retrieving 'blah blah'.")
- Exit Sub
- End If
This same format is being used in multiple locations. There's probably a lot your seeing wrong with this right now, but if not then that's why you should read the rest of this article. Let me go through this step by step.
The developer is using objects that use the interface IDispose. The second thing you'll notice is there is not one try-catch in this entire section. If the connection mysteriously disappears the program will terminate immediately. The end user will have no idea what's going on. Crash!
Now let's say it gets past that. Maybe he/she finally put a try-catch around the Fill() function. The dataset has an exception, but the catch just says a message and it continues on. If the dt_dataadapter is nothing it then goes and disposes of the dt_dataadapter. You can't dispose nothing. So now this results in the application crashing.
Let's choose one more scenario. Let's say this function is called and is surrounded in a Try-Catch. Now the application doesn't crash, however the data adapter and the command is never released from memory. Now you have a memory crisis on your hands. If this happens enough then the application will crash.
The appropriate and best way to avoid everything that has happened above is by using the Using statement. The example below is about 1,000 times better, easier to read, and this won't cause any memory leakage.
Code Snippet
- Using Command As New SqlClient.SqlCommand("blah, blah", dataConnection)
- Command.Parameters.AddWithValue("@ID", 0)
- Using Adapter As New SqlClient.SqlDataAdapter(Command)
- Using Data As New DataSet
- Try
- Adapter.Fill(Data)
- Catch ex As Exception
- MessageBox.Show("Failed retrieving 'blah blah'.")
- Exit Sub
- End Try
- If Not Data Is Nothing AndAlso Data.Tables.Count > 0 AndAlso Data.Tables(0).Rows.Count > 0 Then
- ' Do something with the data here.
- Else
- MessageBox.Show("Failed retrieving 'blah blah'.")
- Exit Sub
- End If
- End Using
- End Using
- End Using
This works because whenever this method is completed it will automatically call the dispose for each object that uses the Using statement.
If you see anything wrong, or have any questions, please leave a message.
No comments:
Post a Comment