资源和效率

时间:2010-12-14 17:36:51

标签: vb.net multithreading class performance

所以在我试图建立一个利用yahoo messenger SDK的CMS系统。这个想法是让自助机器人能够引导客户解决某些问题。对话由两种方法运行。存在一个脚本以回应通用响应。在客户收到的每条消息中,程序将查找将触发XML文件响应的certan关键字和问题。如果它找到一个它继续脚本。该计划有效,但需要付出代价。它是一个巨大的资源猪。在程序中,我有一个类来处理所有的yahoo信使功能,如登录,注销,接收和发送消息。我也有一个课程,我称之为对话。这样就可以保留消息来源的位置,信息的来源以及脚本对话中的位置。在我的主程序中,我根据有多少不同的站点帮助我正在使用的帐户来初始化客户端类的X数量。每次收到一条消息时,它都会创建一个新的会话类,因为它存在或者它会检查现有的会话并找到sripted的位置。它显然也会对传入消息中的关键字进行所有检查。这是我收到消息的共享事件处理程序的代码。我的问题是,无论如何都要提高效率。

    Private Sub yahooclients_OnRec(ByVal sender As Object, ByVal buddy As String, ByVal message As String)
    TotalRec = TotalRec + 1

    Try


        Dim c As YahooClient = CType(sender, YahooClient) 'Yahoo Client To Send Message From 
        showLog("From:" & buddy & " To:" & c.Account & " Message:" & message)
        Dim msgSplit As String()
        Dim retmsg As String
        Dim smsg As String()
        Dim n1 As XmlNode
        Dim sran As New Random 'Random SPlit Message
        Dim domran As New Random 'Random Domain ID
        Dim Found1 As Boolean = False
        Dim FoundIt As Integer = 0
        Dim i As Integer = 0 'Keyword Counter
        'Check Message For KeyWords By Splitting Each phrase by spaces
        msgSplit = Split(message, " ")
        For Each word In msgSplit
            For Each value In KeywordInd
                If value = word Then
                    n1 = m_nodelist.Item(i)
                    retmsg = n1.InnerText
                    GoTo ScrubMessage
                End If
                i = i + 1
            Next
            i = 0
        Next

        'Check For Conversations
        If convos.Count = 0 Then
            convos.Add(New Conversation(c.Account, buddy, 0))
            retmsg = Script(0)
            GoTo ScrubMessage
        Else
            For A As Integer = 0 To (convos.Count - 1)
                If InStr(convos(A).TUser, c.Account) > 0 And InStr(convos(A).FUser, buddy) > 0 Then
                    Found1 = True
                    Exit For
                End If
                FoundIt = FoundIt + 1
            Next
            If Found1 = True Then
                convos(FoundIt).SPosition = convos(FoundIt).SPosition + 1
                'Send Next Position In Script
                If convos(FoundIt).SPosition > (Script.Length - 1) Then
                    If convos(FoundIt).SPosition = Script.Length Then
                        TotalScript = TotalScript + 1
                        ToolStripStatusLabel10.Text = TotalScript
                    End If
                    Exit Sub
                End If
                retmsg = Script(convos(FoundIt).SPosition)
                GoTo ScrubMessage
            Else
                convos.Add(New Conversation(c.Account, buddy, 0))
                retmsg = Script(0)
                GoTo ScrubMessage
            End If
        End If

ScrubMessage:             '剥离|             smsg =分裂(retmsg,“|”)

        'Pull A Random Response
        If smsg.Length > 1 Then
            retmsg = smsg(sran.Next(0, (smsg.Length) - 1))
        Else
            retmsg = smsg(0)
        End If


        'Check For Domain Indicator
        If InStr(retmsg, "%") > 0 Then
            TotalLink = TotalLink + 1
        End If
        retmsg = Replace(retmsg, "%s", Domains(domran.Next(0, (Domains.Length - 1))))

        If CheckBox2.Checked = True Then 'send Message With Font and Color
            retmsg = "<font face=" & """" & fname & """" & ">" & "[#FF80C0m" & retmsg & "</font>"
        End If


        showLog(("Sending Message: " & retmsg & " To: " & buddy & " From: " & c.Account))
        c.SendMessage(buddy, retmsg)
        TotalSent = TotalSent + 1
        ToolStripStatusLabel4.Text = TotalSent 'Updates Sent Counter
        ToolStripStatusLabel6.Text = TotalRec 'Updates Rec Counter
        ToolStripStatusLabel8.Text = TotalLink 'Updates Links counter

    Catch ex As Exception
        showLog(ex.ToString)
    End Try

End Sub

该程序变得非常无助,很多帐户都在提问等。

1 个答案:

答案 0 :(得分:0)

有些事情看起来像是一个好的开始。

1)将ScrubMessage之后的代码拉入其自己的函数中,该函数将所需的信息作为参数。然后用呼叫替换所有GoTos。这可能不会提高性能,但使大多数人更容易理解代码(并且惯例说原始的恶作剧是邪恶的)。

Sub ScrubAndSendMessage(response As String, client As YahooClient)
    'code after label here with needed local variables
End Sub

2)您正在搜索每个传入消息的每个单词的列表。根据用法,KeywordInd和m_nodelist可能会声明如下:

Dim KeywordInd As List(Of String)
Dim m_nodelist As List(Of XmlNode) 'or whatever type has the inner text

由于关键字列表似乎是值的节点列表的关键,我建议使用字典来简化代码并可能提高速度。

Dim wordResponse As New Dictionary(Of String, String)

其中键是来自KeywordInd的字词,而值是来自InnerText的{​​{1}},可让您说出

m_nodelist

3)尝试直接将对话与YahooClient对象相关联,这样您就不必每次都能查找对话。当您这样做时,您还可以确保在需要时与每个客户关联For Each word In msgSplit If wordResponse.ContainsKey(word) Then ScrubMessage(wordResponse(word)) Exit Sub End If Next

4)您正在直接与处理程序中的UI组件进行交互。这要求所有客户端的所有处理程序都在UI线程上运行。您可能最好从此处理程序中引发一些事件,并让表单处理事件并根据需要发布到UI线程。事件可能是ConversationScriptPositionAdvanced或类似的事情。然后,表单/控件可以处理这些事件并根据您选择的UI框架使用的模式发布到UI线程,您应该能够通过快速搜索找到该模式。