我试图编写一个可用于创建客户端/服务器应用程序的小型异步套接字库。如果我将其保留在表单中,我可以使所有代码运行正常,但是如果我尝试将其移出到自己的类中,我无法弄清楚如何使用连接状态更新表单,这样的事情。下面是代码,缩短了一点只是为了使这更容易阅读和输入。
表格代码:
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
该课程实际上有更多,但在第一条消息发出后我再也没有得到任何东西。我不知道从哪里开始。我尝试了很多不同的方法,我在谷歌搜索中发现,有些来自这里,有些不是。有人有什么想法吗?
答案 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