【问题标题】:Mysql connections not closing with VB.NET applicationMysql 连接未与 VB.NET 应用程序关闭
【发布时间】:2021-04-11 03:18:42
【问题描述】:

这是我第一次来这里,因为这个问题我要疯了:

我正在使用多种类型的连接(mysql、odbc 和 SQL 服务器)开发一个带有 VB.NET 的 Windows 窗体应用程序,在我进入 MySQL 之前一切正常。 MySQL服务器是一个物理的windows 7 pc,我通过IPSEC VPN TUNNEL连接到它。

我需要每 x 秒执行 2 个 MySQL 连接,如果我在第一个连接后得到某种类型的结果,那么我将打开第二个连接,以此类推每 x 秒(这都写在我的 timer.tick 事件中处理程序)。 问题是 MySQL 服务器上的一些连接经常在 MySQL 服务器上保持活动状态(已建立),我不知道为什么......代码看起来很好,在正确的时间声明了打开和关闭方法,我我也尝试过 Dispose、ClearPool 和 ClearAllPools 方法,但我一直保持这些连接,直到我关闭程序或达到连接限制。

代码如下:

类连接:

   Public Sub connMySQL()
    Dim connstring As String
    Try
        If stabilimento = "1PR" Then
            If cesoia = "" Then
                connstring = "server=192.168.123.18;userid=xx;password=xx;database=xx;Connect Timeout=30"
            Else
                connstring = "server=192.168.123.253;userid=xx;password=xx;database=xx;Connect Timeout=30"
            End If

        End If
        If stabilimento = "2PR" Then
            If cesoia = "" Then
                connstring = "server=192.168.1.18;userid=xx;password=xx;database=xx;Connect Timeout=30"
            Else
                connstring = "server=192.168.123.253;userid=root;password=xx;database=xx;Connect Timeout=30"
            End If
        End If
   
        conMySql = New MySqlConnection(connstring)
        If conMySql.State = ConnectionState.Closed Then

            conMySql.Open()
              
        End If

    Catch ex As Exception
        MsgBox(ex.ToString)
    End Try
End Sub

执行迭代的类:

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick

   connMySQL()
   comm = New MySqlCommand("SELECT count_1,count_2,start_stop,data_ora,id FROM plc_contatori where plc_nome='" + plc_nome + "' and data_ora > '" + data_ieri.ToString("yyyy/MM/dd") + "' order by data_ora desc limit 1", conMySql)

   dr = comm.ExecuteReader()
   While (dr.Read())
       count_1(0) = dr.GetValue(0)

       start_stop(0) = dr.GetValue(2)
       data_ora(0) = dr.GetValue(3)
       If id <> dr.GetValue(4) And count_2(0) <> dr.GetValue(1) Then
           id = dr.GetValue(4)
           count_2(0) = dr.GetValue(1)
       Else
           Exit Sub
       End If
   End While

   dr.Close()
   dr.Dispose()
   conMySql.Close()
   conMySql.Dispose()
   conMySql.ClearPool(conMySql)
   conMySql.ClearAllPools()

   If Not conMySql Is Nothing Then conMySql = Nothing
   comm.Dispose()

        
   If start_stop(0) = 1 Then
       Exit Sub
   End If
       

   Dim dum_count_2 As Integer = count_2(0) - 1       
   connMySQL()
   comm = New MySqlCommand("select count_1,count_2,start_stop,data_ora from plc_contatori where  plc_nome='" + plc_nome + "' and data_ora > '" + data_ieri.ToString("yyyy/MM/dd") + "'  AND count_2=" + dum_count_2.ToString + " ORDER BY data_ora desc limit 1", conMySql)
   dr = comm.ExecuteReader()
   While (dr.Read())
       count_1(1) = dr.GetValue(0)
       count_2(1) = dr.GetValue(1)
       start_stop(1) = dr.GetValue(2)
       data_ora(1) = dr.GetValue(3)
   End While

   dr.Close()
   dr.Dispose()
   conMySql.Close()
   conMySql.Dispose()
   conMySql.ClearPool(conMySql)
   conMySql.ClearAllPools()
   If Not conMySql Is Nothing Then conMySql = Nothing

   comm.Dispose()


   If count_1(0) = count_1(1) And start_stop(1) <> 1 And count_2(0) <> count_2(1) Then
      'sub that reads some values from an odbc connection
       CheckFermo()

   End If

End Sub

请注意,我没有在这部分代码中声明的变量是在表单的公共类中声明的。

我想知道可能出了什么问题...也许第二个连接是在服务器关闭第一个连接之前建立的?

【问题讨论】:

  • 我不会在字段conMySql 中设置连接的子程序,而是让connMySQL 成为一个返回MySqlConnection 的函数。在Timer1_Tick 中使用它在using 块中,如Using con as MySqlConnection = connMySQL() .... End Using。这应该注意正确关闭和处理连接
  • @AlexB。我应该将两个数据读取器放在一个 using 中还是将它们与 2 using 分开?
  • 任何选项都可以,但我只会使用一个连接
  • 我发现 data_ora 有问题。这是一个日期字段吗?是在数据库中输入日期吗?如果不是,所有字符串是否都以 > 符号可以使用的格式存储?我认为日期应该存储为日期。

标签: mysql vb.net visual-studio connection mysqlconnection


【解决方案1】:

我将connMySQL 方法更改为返回连接字符串的函数。我已经声明了几个变量,所以代码是有意义的。我对数据类型做了几个假设。如果这些值实际上存储为字符串,您可能必须将其更改回 String 和 VarChar。 (我希望他们不是)

您可以使用单个连接,但所有分配和比较都将在打开连接时发生。

Private stabilimento As String
Private cesoia As String
Public Function connMySQL() As String
    Dim connstring As String
    Select Case True
        Case stabilimento = "1PR" And cesoia = ""
            connstring = "server=192.168.123.18;userid=xx;password=xx;database=xx;Connect Timeout=30"
        Case stabilimento = "2PR" And cesoia = ""
            connstring = "server=192.168.1.18;userid=xx;password=xx;database=xx;Connect Timeout=30"
        Case Else
            connstring = "server=192.168.123.253;userid=root;password=xx;database=xx;Connect Timeout=30"
    End Select
    Return connstring
End Function

Private count_1(10) As Integer
Private count_2(10) As Integer
Private start_stop(10) As Integer
Private data_ora(10) As Date
Private id As Integer
Private plc_nome As String
Private data_ieri As Date

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    Using dt As New DataTable
        Using cn As New MySqlConnection(connMySQL),
            comm = New MySqlCommand("SELECT count_1,count_2,start_stop,data_ora,id 
                                    FROM plc_contatori 
                                    where plc_nome= @plcNome and data_ora > @dataOra 
                                    order by data_ora desc 
                                    limit 1", cn)
            comm.Parameters.Add("plcNome", MySqlDbType.VarChar).Value = plc_nome
            comm.Parameters.Add("dataOra", MySqlDbType.Date).Value = data_ieri '.ToString("yyyy/MM/dd")
            cn.Open()
            Using dr = comm.ExecuteReader
                dt.Load(dr)
            End Using 'closes and disposes reader
        End Using 'closes and dispose connection and command
        count_1(0) = CInt(dt(0)(0))
        start_stop(0) = CInt(dt(0)(2))
        data_ora(0) = CDate(dt(0)(3))
        If id <> CInt(dt(0)(4)) AndAlso count_2(0) <> CInt(dt(0)(1)) Then
            id = CInt(dt(0)(4))
            count_2(0) = CInt(dt(0)(1))
        Else
            Exit Sub
        End If
    End Using 'disposes DataTable
    If start_stop(0) = 1 Then
        Exit Sub
    End If


    Dim dum_count_2 As Integer = count_2(0) - 1
    Using dt As New DataTable
        Using cn As New MySqlConnection(connMySQL),
            comm As New MySqlCommand("select count_1,count_2,start_stop,data_ora 
                                        from plc_contatori 
                                        where  plc_nome= @plcNome 
                                        and data_ora > @dataOra 
                                        AND count_2= @count2 
                                        ORDER BY data_ora desc 
                                        limit 1", cn)
            comm.Parameters.Add("@plcNome", MySqlDbType.VarChar).Value = plc_nome
            comm.Parameters.Add("@dataOra", MySqlDbType.Date).Value = data_ieri '.ToString("yyyy/MM/dd")
            comm.Parameters.Add("@count2", MySqlDbType.Int32).Value = dum_count_2 '.ToString
            cn.Open()
            Using dr = comm.ExecuteReader()
                dt.Load(dr)
            End Using
        End Using
        count_1(1) = CInt(dt(0)(0))
        count_2(1) = CInt(dt(0)(1))
        start_stop(1) = CInt(dt(0)(2))
        data_ora(1) = CDate(dt(0)(3))
    End Using
    If count_1(0) = count_1(1) AndAlso start_stop(1) <> 1 AndAlso count_2(0) <> count_2(1) Then
        'sub that reads some values from an odbc connection
        CheckFermo()
    End If
End Sub

【讨论】:

  • 感谢@Mary 的代码!我已经应用了修改。请注意,“Using cn As New MySqlConnection(connMySQL)”后面有几个逗号不应该出现在这里。现在看起来一切都很好,明天我会确认你,因为今天没有记录被写入数据库,而且每 5 秒只执行第一个连接。我还注意到“使用”不会在 MySQL 服务器上创建任何 TIME_WAIT 会话,这也很棒。
  • @Casian55 Using cn As New MySqlConnection(connMySQL), 后面的逗号应该在那里。它将 Using 块扩展到下一行,从而将命令包含在 Using 块中。您可以添加另一个包含命令的 Using 块,但逗号会节省一些缩进。
  • 对不起,我不知道。现在一切正常,没有任何连接处于打开状态。非常感谢您的帮助!
猜你喜欢
  • 2010-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-14
  • 2014-12-18
  • 1970-01-01
  • 2014-08-17
相关资源
最近更新 更多