vb.net:listbox.items.add()在同一个类中抛出异常

时间:2012-10-25 16:02:22

标签: vb.net multithreading visual-studio-2010 delegates invoke

我甚至不确定我是否理解这种情况足以提出一个合适的标题。我来自对VB6的谦虚理解,不得不为VB 2010攀登陡峭的学习曲线。

我正在尝试创建一个与我的企业iPhone应用程序通信的多客户端服务器程序。我在这里找到了一个相对简单的例子:http://www.strokenine.com/blog/?p=218。我已经能够修改代码足以使它适用于我的应用程序,但有一个小问题:我无法访问表单上的控件来添加项目,即使该方法是在表单的类中调用的。 (我也在原始代码上尝试了这个,它做了同样的事情。我不知道作者是如何设法让它工作的。)

以下是相关代码段:

Public Class Server 'The form with the controls is on/in this class.
Dim clients As New Hashtable 'new database (hashtable) to hold the clients


    Sub recieved(ByVal msg As String, ByVal client As ConnectedClient)
    Dim message() As String = msg.Split("|") 'make an array with elements of the message recieved
    Select Case message(0) 'process by the first element in the array
        Case "CHAT" 'if it's CHAT
            TextBox3.Text &= client.name & " says: " & " " & message(1) & vbNewLine 'add the message to the chatbox
            sendallbutone(message(1), client.name) 'this will update all clients with the new message
            '                                       and it will not send the message to the client it recieved it from :)
        Case "LOGIN" 'A client has connected
            clients.Add(client, client.name) 'add the client to our database (a hashtable)
            ListBox1.Items.Add(client.name) 'add the client to the listbox to display the new user
    End Select

End Sub

在Case“LOGIN”下,代码尝试将登录ID添加到列表框中。它抛出一个异常:“System.Windows.Forms.dll中出现'System.InvalidOperationException'类型的第一次机会异常”列表框(所有控件,就此而言)属于同一个类,Server.vb和Server.vb [设计]。

数据来自另一个客户端登录时创建的类,这会引发切换回Server类的事件:

Public Class ConnectedClient

Public Event gotmessage(ByVal message As String, ByVal client As ConnectedClient)    'this is raised when we get a message from the client
Public Event disconnected(ByVal client As ConnectedClient)    'this is raised when we get the client disconnects

Sub read(ByVal ar As IAsyncResult) 'this will process all messages being recieved
    Try
        Dim sr As New StreamReader(cli.GetStream) 'initialize a new streamreader which will read from the client's stream
        Dim msg As String = sr.ReadLine() 'create a new variable which will be used to hold the message being read
        RaiseEvent gotmessage(msg, Me) 'tell the server a message has been recieved. Me is passed as an argument which represents 
        '                               the current client which it has recieved the message from to perform any client specific
        '                               tasks if needed
        cli.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf read, Nothing) 'continue reading from the stream
    Catch ex As Exception
        Try 'if an error occurs in the reading purpose, we will try to read again to see if we still can read
            Dim sr As New StreamReader(cli.GetStream) 'initialize a new streamreader which will read from the client's stream
            Dim msg As String = sr.ReadLine() 'create a new variable which will be used to hold the message being read
            RaiseEvent gotmessage(msg, Me) 'tell the server a message has been recieved. Me is passed as an argument which represents 
            '                               the current client which it has recieved the message from to perform any client specific
            '                               tasks if needed
            cli.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf read, Nothing) 'continue reading from the stream
        Catch ' IF WE STILL CANNOT READ
            RaiseEvent disconnected(Me)  'WE CAN ASSUME THE CLIENT HAS DISCONNECTED
        End Try

    End Try
End Sub

我希望我能理解这一切。这一切似乎来回反弹,似乎很复杂。

我尝试过使用Me.listbox1和Server.listbox1以及其他一些类似的结构,但无济于事。

我正在阅读很多关于Invoke和Delegates的内容,但如果方法和控件属于同一个类,那么这是必要的吗?或者我对一个班级有什么基本的误解?

非常感谢我能得到的任何帮助。

1 个答案:

答案 0 :(得分:1)

    Private Delegate Sub UpdateListDelegate(byval itemName as string)
    Private Sub UpdateList(byval itemName as string)
    If Me.InvokeRequired Then
        Me.Invoke(New UpdateListDelegate(AddressOf UpdateList), itemName)
    Else
        ' UpdateList
        ' add list add code
        ListBox1.Items.Add(itemName)
    End If
    End Sub

在上面添加,然后替换:

   ListBox1.Items.Add(client.name)

   UpdateList(client.name)

有用吗?检查语法,输入时可能会输入拼写错误。