【问题标题】:VB.NET MySQL sometimes, but not always freezing whole applicationVB.NET MySQL 有时,但并不总是冻结整个应用程序
【发布时间】:2015-08-28 10:40:44
【问题描述】:

我用

  • vb.NET 2013
  • 框架 2.0
  • 来自 .Net Framework 的 ODBC 连接
  • ODBC MySQL 连接器 3.51

有时,但并非总是如此,当我查询数据库时,程序没有响应并且根本没有错误。

重新启动应用程序并再次运行完全相同的操作后,一切正常。

        Function GetData(ByVal xxx1 As Integer, ByVal xxx2 As DateTime, ByVal xxx3 As DateTime) As DataTable
        Dim dt As DataTable = NewDT.GetData

        Try
            SyncLock Master_Con
                Using cmd As New OdbcCommand(myCmdStr, Master_Con)
                    cmd.CommandTimeout = SQLCmd.intCmdTimeout '3
                    cmd.Parameters.Add("xxx1", OdbcType.Int).Value = xxx1
                    cmd.Parameters.Add("xxx2", OdbcType.NVarChar).Value = xxx2
                    cmd.Parameters.Add("xxx3", OdbcType.NVarChar).Value = xxx3
                    Using dr As OdbcDataReader = cmd.ExecuteReader
                        If dr.HasRows Then
                            Dim rowcount As Integer = 0
                            While dr.Read()
                                dt.Rows.Add()
                                For count As Integer = 0 To (dr.FieldCount - 1)
                                    dt.Rows(rowcount).Item(count) = dr(count)
                                Next
                                rowcount = rowcount + 1
                            End While
                        End If
                    End Using
                End Using
            End SyncLock

        Catch OdbcEx As OdbcException
            MessageBox.Show("ODBC-Fehler bei Funktion 'GetData'. " & vbCrLf & vbCrLf & OdbcEx.Message, "App", MessageBoxButtons.OK, MessageBoxIcon.Error)

        Catch ex As Exception
            MessageBox.Show("Systemfehler bei Funktion 'GetData'. " & vbCrLf & vbCrLf & ex.Message, "App", MessageBoxButtons.OK, MessageBoxIcon.Error)

        End Try

        Debug.WriteLine("done.")
        Return dt

    End Function

我的日志是这样写的:

GetData (28.08.15 - 28.08.15)... done.
GetData2 (28.08.15)... done.
DelData... done.
GetData (28.08.15 - 28.08.15)... done.
GetData2 (28.08.15)... done.
GetData (27.08.15 - 27.08.15)... done.
GetData2 (27.08.15)... done.
GetData (26.08.15 - 26.08.15)... 

程序在运行 cmd.ExecuteReader 时一直没有响应。 由于我多次以完全相同的方式运行命令,我猜测它与超时或mysql服务器/连接繁忙有关。

但由于它从不引发错误/odbc 错误,而且它只是时不时发生,我不知道如何解决它。

任何帮助都会很好!

【问题讨论】:

  • 应用程序被冻结的最可能原因是 GUI 线程很忙,无法刷新表单的外观。在您的情况下,我猜有时数据的检索速度足以让您注意到冻结。在这些情况下,最好的解决方案是依赖多线程(即,在不同的线程中运行需要太长时间的部分); BackgroundWorker 对于这种情况非常方便。这里有一些简单的例子展示了如何实现它:dotnetperls.com/backgroundworker-vbnet
  • 另一方面,不可能知道为什么在某些情况下您的连接速度较慢(甚至完全卡住)。您应该仔细分析您的具体情况;并最终发布一个清楚描述他们的问题(不是这个问题),以便有人可能会提出一些建议。
  • 我在询问要查找或分析的内容。 -> 将它放在一个自己的线程中是可能的,但这不只是一种解决方法吗?线程可能也会冻结。然后我必须制作一个自己的超时循环并杀死它。如果它是唯一的解决方案...:/
  • 没有。线程不会冻结。您看到的冻结是 GUI 没有执行它应该执行的操作的结果。表单正在系统地更新很多东西(例如,由其中包含的所有控件触发的事件)。所有表单动作(相当于 GUI 中其余控件执行的所有动作)都在 GUI 线程中完成。如果 GUI 线程忙于处理某些事情(例如,循环或从数据库或文件中获取信息),所有这些操作都必须等到它再次空闲。如果您将这些操作放在不同的线程中,则无需等待。
  • 将线程视为 1 车宽的道路(不可能被超越)。如果您不依赖多线程,则只有一个线程/路径供 GUI 使用(如前所述,它不断地做您没有意识到的事情)以及您所做的所有事情。如果您执行给定操作的时间过长(并且不希望其他操作等待它),您将不得不创建一个不同的线程。作为一般规则,任何执行一些耗时操作(读取文件、连接到数据库等)的应用程序都应该至少依赖两个线程/路径。一个用于 GUI,另一个用于其余部分。

标签: mysql database vb.net odbc freeze


【解决方案1】:

问题在于有时会出现死锁。

在其自己的函数中调用 SQLCommand 执行后,它现在可以正常工作了。

Private Delegate Function ExecScalarDelegate(ByVal cmd As System.Data.Odbc.OdbcCommand, _ 
ByRef ReturnValue As Object) As Boolean

Private Shared Function ExecScalar(ByVal cmd As System.Data.Odbc.OdbcCommand, _ 
ByRef ReturnValue As Object) As Boolean
    ExecScalar = False

    SyncLock cmd.Connection
        ReturnValue = cmd.ExecuteScalar()
    End SyncLock
    Return True
End Function

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多