странное исключение asp.net каждые три минуты примерно - PullRequest
4 голосов
/ 15 марта 2012

Я пытаюсь создать очень простую страницу aspx, которая извлекает некоторые данные из базы данных mysql.Страница строится без проблем.(aspx содержит только форму по умолчанию и div для печати некоторых данных)

Default.aspx.vb:

Imports System.Configuration
Imports System.Data
Imports MySql
Imports MySql.Data
Imports MySql.Data.MySqlClient

Partial Class _Default
     Inherits System.Web.UI.Page

    Private cnstr As String =     ConfigurationManager.ConnectionStrings.Item("thisdb").ConnectionString

    Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load

        Dim cn As New MySqlConnection(cnstr)
        Dim cmd As New MySqlCommand("SELECT user_firstname,user_lastname FROM tb_users;", cn)
        cmd.CommandType = CommandType.Text
        Dim dt As DataTable
        dt = GetDataTableMySQL(cmd)
        If dt.Rows.Count > 0 Then
            testdiv.InnerHtml = dt.Rows(0).Item("user_firstname")
            testdiv.InnerHtml += "<br/>" & dt.Rows(0).Item("user_lastname")
        End If
        dt.Dispose()
        cmd.Dispose()
        cn.Dispose()

    End Sub

    Private Function GetDataTableMySQL(ByVal cmd As MySqlCommand) As DataTable
        Dim da As New MySqlDataAdapter()
        Dim dt As New DataTable()
        Try
           cmd.Connection.Open()
           da.SelectCommand = cmd
           da.Fill(dt)
           Return dt
        Catch ex As MySqlException
            Throw ex
        Catch ex As Exception
            Throw New Exception(ex.Message)
        Finally
            cmd.Connection.Close()
            da.Dispose()
       End Try
    End Function

End Class

Web.config:

<?xml version="1.0"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->
<configuration>
  <system.web>
    <compilation debug="true" strict="false" explicit="true" targetFramework="4.0">
      <assemblies>
        <add assembly="MySql.Data, Version=6.4.4.0, Culture=neutral, PublicKeyToken=C5687FC88969C44D"/>
      </assemblies>
    </compilation>
    <customErrors mode="Off"/>
  </system.web>
  <connectionStrings>
    <add name="thisdb" connectionString="Server=localhost;Database=mydatabase;Uid=mydbuser;Pwd=dbpasswd;CharSet=UTF8; "/>
  </connectionStrings>
</configuration>

Когда я просматриваю URL страницы, она работает отлично.Если я продолжу обновлять страницу, все будет работать без проблем.

Теперь возникает раздражающая проблема ...

Если я оставляю страницу простаивающей в течение примерно 3-4 минут, изатем нажмите «Обновить». Я всегда получаю следующее исключение:

Указанный ключ отсутствует в словаре.

Описание: во время выполнения текущего возникло необработанное исключениевеб-запрос.Пожалуйста, просмотрите трассировку стека для получения дополнительной информации об ошибке и о том, где она возникла в коде.

Сведения об исключении: System.Exception: Указанный ключ отсутствует в словаре.

Ошибка источника:

Во время выполнения текущей веб-страницы возникло необработанное исключениезапрос.Информацию о происхождении и местонахождении исключения можно определить с помощью приведенной ниже трассировки стека исключений.

Трассировка стека:

[Исключение: указанный ключ отсутствует в словаре.]
_Default.GetDataTableMySQL (MySqlCommand cmd) +236 _Default.Page_Load (отправитель объекта, EventArgs e) +112 System.Web.UI.Control.OnLoad (EventArgs e) + 91
System.Web.UI.Control.Loadurec) + 74
System.Web.UI.Page.ProcessRequestMain (логическое значение includeStagesBeforeAsyncPoint, логическое значение includeStagesAfterAsyncPoint) + 2207

Информация о версии: Microsoft .NET Framework Версия: 4.0.30319;ASP.NET версия: 4.0.30319.272

Если я нажимаю кнопку Обновить еще раз, страница снова работает нормально ... и т. Д.

После нескольких часов поиска в Интернете,единственное, что звучит в связи с моей проблемой, связано с MySQL соединителя / сети:

Документация соединителя / сети гласит:

Начиная с MySQL Connector / Net 6.2, тамэто фоновое задание, которое запускается каждые три минуты и удаляет соединения из пула, которые простаивают (не используются) более трех минут.Очистка пула освобождает ресурсы как на стороне клиента, так и на стороне сервера.Это связано с тем, что на стороне клиента каждое соединение использует сокет, а на стороне сервера каждое соединение использует сокет и поток.

До этого изменения соединения никогда не удалялись из пула, а пул всегдасодержит пиковое количество открытых соединений.Например, веб-приложение, достигшее максимума при 1000 одновременных подключений к базе данных, будет потреблять 1000 потоков и 1000 открытых сокетов на сервере, даже не освобождая эти ресурсы из пула соединений.

Обратите внимание, что соединения, независимо от их возраста, не будут закрыты, если число соединений в пуле меньше или равно значению, установленному параметром строки соединения Min Pool Size.

ОК.Даже если это моя проблема, какой правильный способ подключения -> получить данные -> отключить?

Есть идеи?Это действительно сводит меня с ума!

ОБНОВЛЕНИЕ После предложения @Andrews я изменил функцию "GetDataTableMySQL" следующим образом:

Private Function GetDataTableMySQL(ByVal cmd As MySqlCommand) As DataTable
    Dim dt As New DataTable
    Using da = New MySqlDataAdapter(cmd)
        da.Fill(dt)
    End Using
    Return dt
End Function

(Не удалось решитьпроблема, но я думаю, что это полезно, чтобы показать, как код выглядит сейчас)

Трассировка стека исключения, изменилась на следующее:

[KeyNotFoundException: данный ключ не былприсутствует в словаре.] System.Collections.Generic.Dictionary`2.get_Item (ключ TKey) + 9624829
MySql.Data.MySqlClient.CharSetMap.GetCharacterSet (версия DBVersion, строка CharSetName) + 23
MySq..MySqlClient.CharSetMap.GetEncoding (версия DBVersion, String CharSetName) + 47
MySql.Data.MySqlClient.Driver.Configure (соединение MySqlConnection) +510 MySql.Data.MySqlClient.MySqlConnection.Open () +418 System.Data.Common.DbDataAdapter.FillInternal (набор данных DataSet, DataTable [] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, команда IDbCommand, поведение CommandBehavior) + 123
System.Data.Common.DbDataAdapter.Fill (DataTable [] dataTables, Int32 startRecord, Int32 maxRecords, команда IDbCommand, CommandBehavior поведение) +166 System.Data.Common.DbDataAdapter.Fill (DataTable dataTable) +115 _Default.GetDataTableMySQL (MySqlCommand cmd) + 86
_Default.Page_Load (Отправитель объекта, EventArgs e) +112 System.Web.UI.Control.OnLoad (EventArgs e) + 91
System.Web.UI.Control.LoadRecursive () + 74
System.Web.UI.Page.ProcessRequestMain (Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) + 2207

ОБНОВЛЕНИЕ 2 После прочтения Параметры строки подключения / сетевого соединения Я протестировал свою строку подключения с опцией:

 Pooling=false;

, а затем я протестировал изменение параметра пула на:

 Pooling=no;

При тестировании параметров пула страница никогда не работает! Я получаю исключение "Указанный ключ отсутствует в словаре" каждый раз.

1 Ответ

1 голос
/ 15 марта 2012

Это может не решить проблему, но для DataAdapter.Fill вам не нужно открывать и закрывать соединение самостоятельно.

Кроме того, я подозреваю использование Return в блоке Try - вы могли бысделайте что-нибудь более похожее на

Private Function GetDataTableMySQL(ByVal cmd As MySqlCommand) As DataTable
    Dim dt As DataTable = Nothing
    Using da = New MySqlDataAdapter()
        da.fill(dt)
    End Using
    Return dt
End Function

и проверьте, является ли возвращаемое значение IsNot Nothing, чтобы убедиться, что оно работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...