异步套接字库不更新表单

时间:2011-11-23 21:58:19

标签: vb.net asyncsocket

我试图编写一个可用于创建客户端/服务器应用程序的小型异步套接字库。如果我将其保留在表单中,我可以使所有代码运行正常,但是如果我尝试将其移出到自己的类中,我无法弄清楚如何使用连接状态更新表单,这样的事情。下面是代码,缩短了一点只是为了使这更容易阅读和输入。

表格代码:

Class Form1
Dim Network as NetworkModule

Public Sub Button1_Click(Sender, e) Handles Button1.Click
    Network = New NetworkModule("127.0.0.1", 1234)
End Sub
End Class 'Form1

NetworkModule类:

Class NetworkModule
    Private mSocket as Socket

    Public Sub New(IP as string, Port as Integer)
        Dim remoteEP as New IPEndpoint(IP.Parse(IP), Port)
        mSocket = New Socket(internetwork, stream, tcp)
        mSocket.BeginConnect(remoteEP, New AsyncCallback(AddressOf onConnect), mSocket)
        Notify("Connection to " & remoteEP.ToString)  'This one works
     End Sub 'New

     Private Sub onConnect(ar as IAsyncResult)
         mSocket = CType(ar.AsyncState, Socket)
         mSocket.EndConnect(ar)
         Notify("Connected")  'This one never shows
     End Sub 'onConnect

    Private Delegate Sub _Notify(Msg as String)
    Private Sub Notify(Msg as String)
        If Form1.txtLog.InvokeRequired Then
            Form1.txtLog.Invoke(New _Notify(AddressOf Notify), Msg)
            Exit Sub
        End if
        Form1.txtLog.Text &= Msg & vbcrlf
    End Sub 'Notify
End Class 'NetworkModule

该课程实际上有更多,但在第一条消息发出后我再也没有得到任何东西。我不知道从哪里开始。我尝试了很多不同的方法,我在谷歌搜索中发现,有些来自这里,有些不是。有人有什么想法吗?

1 个答案:

答案 0 :(得分:1)

以下是我将如何重写它:

Class Form1
    Private Network as NetworkModule
    Public NotifyDelegate As NetworkModule.NotifyDelegate

    Public Sub New()
        NotifyDelegate = New NetworkModule.NotifyDelegate(AddressOf Notify)
    End Sub

    Public Sub Button1_Click(Sender, e) Handles Button1.Click
        Network = New NetworkModule("127.0.0.1", 1234, Me)
    End Sub

    Public Sub Notify(Msg As String)
        txtLog.Text &= Msg & vbCrLf
    End Sub
End Class 'Form1

NetworkModule类(部分):

Class NetworkModule
    Public Delegate Sub NotifyDelegate(Msg as String)

    Private Sub Notify(Msg as String)
        If m_Form.InvokeRequired Then
            m_Form.Invoke(Form1.NotifyDelegate, Msg)
        Else
            m_Form.Notify(Msg)
        End If
    End Sub 'Notify

    Private mSocket as Socket

    Private m_Form As Form1

    Public Sub New(IP as string, Port as Integer, oForm As Form1)
        m_Form = oForm
        Dim remoteEP as New IPEndpoint(IP.Parse(IP), Port)
        mSocket = New Socket(internetwork, stream, tcp)
        mSocket.BeginConnect(remoteEP, New AsyncCallback(AddressOf onConnect), mSocket)
        Notify("Connection to " & remoteEP.ToString)  'This one works
     End Sub 'New

使用界面方法更新

比传递表单本身更好的机制是实现接口。要执行此操作,请首先创建接口定义(请注意,为方便起见,委托已移至界面):

Public Interface INotify
    Sub Notify(Msg As String)
    Delegate Sub NotifyDelegate(Msg As String)
End Interface

然后在表单中实现接口。请注意,表单现在确定是否需要Invoke。这允许INotify接口在非UI场景中使用,例如记录到磁盘或事件日志。

Public Class Form1
    Implements INotify

    Public Sub Notify(Msg As String)
        txtLog.Text &= Msg & vbCrLf
    End Sub

    Private Sub INotify_Notify(Msg As String) Implements INotify.Notify
        If Me.InvokeRequired Then
            Me.Invoke(New INotify.NotifyDelegate(AddressOf Notify), Msg)
        Else
            Me.Notify(Msg)
        End If
    End Sub 'Notify

    Private Network As NetworkModule

    Public Sub Button1_Click(Sender, e) Handles Button1.Click
        Network = New NetworkModule("127.0.0.1", 1234, Me)
    End Sub
End Class 'Form1

最后,存储对INotify接口的引用而不是NetworkModule中的Form(请注意,NetworkModule不再需要知道或关心可能需要Invoke):

Public Class NetworkModule
    Public Delegate Sub NotifyDelegate(Msg As String)

    Private m_Notifier As INotify

    Private Sub Notify(Msg As String)
        m_Notifier.Notify(Msg)
    End Sub 'Notify

    Public Sub New(IP As String, Port As Integer, oNotifier As INotify)
        m_Notifier = oNotifier
        ' The addition code here
    End Sub 'New
End Class