Необычно длинная пауза при попытке закрыть ADO.NET объект подключения: это нормально?

#sql-server #vb.net #ado.net

#sql-server #vb.net #ado.net

Вопрос:

Я выполняю простое упражнение по открытию подключения к базе данных SQL Server, извлечению первой записи таблицы из объекта DataReader, а затем закрытию объекта. Однако я заметил, что при закрытии соединения возникает небольшая задержка, около 5 секунд или около того. Однако задержка возникает только после того, как объект command выполняет указанный запрос. Я работал с подобной настройкой раньше и не помню, чтобы при закрытии соединения была такая длительная задержка.

    Public Sub TestDb()
    Dim cnStrBuilder As New SqlClient.SqlConnectionStringBuilder
    Dim cn As New SqlClient.SqlConnection
    Dim sqlSelectName As New SqlClient.SqlCommand
    Dim drName As SqlClient.SqlDataReader
    Dim newName As New SymName
    Dim i As Integer

    cnStrBuilder.UserID = "sa"
    cnStrBuilder.ConnectTimeout = 30
    cnStrBuilder.Password = ""
    cnStrBuilder.PersistSecurityInfo = True
    cnStrBuilder.DataSource = "EMARKETFL_DB"
    cnStrBuilder.InitialCatalog = "EmailMarketing"

    sqlSelectName.CommandType = CommandType.Text
    sqlSelectName.CommandText = "SELECT * FROM [NAME]"

    System.Console.WriteLine(cnStrBuilder.ConnectionString)

    cn.ConnectionString = cnStrBuilder.ConnectionString

    Try
        If cn.State = ConnectionState.Closed Then
            cn.Open()
        End If
        System.Console.WriteLine("Connection success")

        sqlSelectName.Connection = cn

        System.Console.WriteLine("Execute Reader")
        drName = sqlSelectName.ExecuteReader

        If drName.HasRows = True Then
            System.Console.WriteLine("Read Row")
            drName.Read()

            For i = 0 To drName.FieldCount - 1
                Console.WriteLine(drName.Item(i).ToString)
            Next
        End If

        System.Console.WriteLine("Closing connection")

        sqlSelectName.Connection.Close()

    Catch ex As Exception
        System.Console.WriteLine("Something Happened")
        System.Console.WriteLine(ex.Message)
    End Try

System.Console.WriteLine("Done.")

End Sub
  

Если я опущу строки

 'System.Console.WriteLine("Execute Reader")
'drName = sqlSelectName.ExecuteReader
'
'If drName.HasRows = True Then
'    System.Console.WriteLine("Read Row")
'    drName.Read()
'
'    For i = 0 To drName.FieldCount - 1
'        Console.WriteLine(drName.Item(i).ToString)
'    Next
'End If
  

Соединение закрывается почти сразу. Что дает? Я сузил его до того, где .ExecuteReader строка, вызывающая задержку в соединении, закрывается. Что вызывает задержку и как мне ее устранить?

Ответ №1:

Вы указываете SQL Server на получение всей таблицы. Тем не менее, после первой строки вы останавливаетесь и закрываете соединение. Как и вы, я ожидал бы немедленного закрытия соединения, но, возможно, сервер занят буферизацией таблицы в место, где он может быстро вернуть ваши данные.

Соединение все еще закрывается медленно, если вы запрашиваете у сервера только одну строку? Например.

  sqlSelectName.CommandText = "SELECT TOP 1 * FROM [NAME]"
  

Комментарии:

1. Отличная мысль. Это относительно большая таблица. Я попробую.

Ответ №2:

Как правило, вы должны оборачивать любые объекты, которые реализуют IDisposable, в using statements, которые включают объект подключения. Я бы попробовал реализовать что-то вроде следующего, которое взято из MSDN:

http://msdn.microsoft.com/en-us/library/y6wy5a0f.aspx#Y400

 Public Sub CreateCommand(ByVal queryString As String, _
  ByVal connectionString As String)
    Using connection As New SqlConnection(connectionString)
        Dim command As New SqlCommand(queryString, connection)
        connection.Open()
        Dim reader As SqlDataReader = _
            command.ExecuteReader(CommandBehavior.CloseConnection)
        While reader.Read()
            Console.WriteLine("{0}", reader(0))
        End While
    End Using
End Sub