【发布时间】: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