使用写入队列和多线程

时间:2015-07-09 17:15:49

标签: vb.net multithreading

我有一个进程在一个单独的线程中运行,该线程通过以太网读取数据并为每次读取引发一个事件。然后,通过类树处理此数据。在我的类树的顶部,我想将处理的数据存储到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

1 个答案:

答案 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

此外,您可能希望查找一些关于编写服务的文章,因为如果您希望程序执行无人值守的监视,这种事情作为服务的效果会更好。此外,您可以让一个线程接受命令字符串并将它们添加到队列中,第二个线程将它们写入数据库。