我有一个进程在一个单独的线程中运行,该线程通过以太网读取数据并为每次读取引发一个事件。然后,通过类树处理此数据。在我的类树的顶部,我想将处理的数据存储到SQL表。这种读取速率可能相当快,通常有时但平均速度慢于我对SQL的写入速率。这就是我想要一个队列的原因。此外,我希望我的窗口不要冻结,所以我想要一个单独的线程。
下面的代码有效,但我在多线程方面相当缺乏经验,这是一种完成任务的好方法吗?
Private addLogQueue As New Queue
Private dequeueing As Boolean = False
Public Sub addLogHandler(ByVal machineName As String, ByVal LogTime As Date, ByVal EventLog As String, ByVal EventValue As String)
addLogQueue.Enqueue("INSERT INTO ... some SQL CODE")
Dim Thread1 As New System.Threading.Thread(AddressOf addLog)
Thread1.Start
End Sub
Private Sub addLog()
If Not dequeueing Then
dequeueing = True
While addLogQueue.Count <> 0
Try
SQLCon.Open()
SQLCmd = New SqlCommand(addLogQueue.Dequeue(), SQLCon)
SQLCmd.ExecuteNonQuery()
SQLCon.Close()
Catch ex As Exception
MsgBox(ex.Message)
If SQLCon.State = ConnectionState.Open Then
SQLCon.Close()
End If
End Try
End While
dequeueing = False
End If
End Sub
答案 0 :(得分:0)
我会推荐你阅读文章:Beginners Guide to Threading。此外,出于性能原因,您可能希望保持线程打开,并打开数据库连接,只需使用等待事件来确定是否应检查队列是否有更多条目。请参阅此文章:An Overview of Synchronization。保持连接打开实际上取决于消息的到达频率。非常频繁:保持连接打开,间歇性:使用后关闭。
Dim Thread1 As New System.Threading.Thread(AddressOf addLog)
Private Shared mre As New ManualResetEvent(False)
Private addLogQueue As New Queue
Private shutDown as boolean = false
Public Sub Main
Thread1.Start
End Sub
Public Sub addLogHandler(ByVal machineName As String, ByVal LogTime As Date, ByVal EventLog As String, ByVal EventValue As String)
addLogQueue.Enqueue("INSERT INTO ... some SQL CODE")
mre.Set()
End Sub
Private Sub addLog()
dim cmdString as String
Try
Using SQLCon as New SQLConnection
SQLCon.Open()
While Not shutDown
mre.WaitOne()
mre.Reset()
While addLogQueue.Count <> 0
cmdString = addLogQueue.Dequeue()
SQLCmd = New SqlCommand(cmdString, SQLCon)
SQLCmd.ExecuteNonQuery()
End While
End While
End Using
Catch ex As Exception
My.Application.Log.WriteException(ex,TraceEventType.Error, cmdString)
End Try
End Sub
此外,您可能希望查找一些关于编写服务的文章,因为如果您希望程序执行无人值守的监视,这种事情作为服务的效果会更好。此外,您可以让一个线程接受命令字符串并将它们添加到队列中,第二个线程将它们写入数据库。