所以在我试图建立一个利用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
该程序变得非常无助,很多帐户都在提问等。
答案 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线程。事件可能是Conversation
和ScriptPositionAdvanced
或类似的事情。然后,表单/控件可以处理这些事件并根据您选择的UI框架使用的模式发布到UI线程,您应该能够通过快速搜索找到该模式。