如何在Windows窗体应用程序(VB.NET)中使用UdpClient.BeginReceive

时间:2013-08-31 18:06:22

标签: vb.net asynchronous udp

我对下面代码的意图是在我的表单打开时开始查找(异步)UDP数据报。当收到数据报时,我想做的就是调用在主线程上运行的过程(传递收到的消息),然后重新开始寻找另一个数据报。假设代码是正确的,直到数据报出现,我该如何进行下两步?我真的很困惑跨线程操作,代表等等。谢谢。另外,我想继续使用.Net 4.0。

Const RcvPort As Integer = 33900
Public RRWEndPoint As IPEndPoint = New IPEndPoint(myIPaddr, RcvPort)
Public SiteEndPoint As IPEndPoint = New IPEndPoint(IPAddress.Any, RcvPort)
Public dgClient As UdpClient = New UdpClient(RRWEndPoint)

Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
    dgClient.BeginReceive(AddressOf UDPRecv, Nothing)
End Sub

Public Sub UDPRecv(ar As IAsyncResult)
    Dim recvBytes As Byte() = dgClient.EndReceive(ar, SiteEndPoint)
    Dim recvMsg As String = Encoding.UTF8.GetString(recvBytes)

    dgClient.BeginReceive(AddressOf UDPRecv, Nothing)
End Sub

1 个答案:

答案 0 :(得分:4)

您的UDPRecv()方法将在I / O完成线程上运行。任何从该线程更新UI的尝试都会炸毁您的程序。您必须使用表单的BeginInvoke()方法将字符串传递给在UI线程上运行的方法。当程序终止时,您还必须处理套接字关闭,这需要捕获EndReceive()调用将抛出的ObjectDisposedException。

所以看起来像这样:

Public Sub UDPRecv(ar As IAsyncResult)
    Try
        '' Next statement will throw when the socket was closed
        Dim recvBytes As Byte() = dgClient.EndReceive(ar, SiteEndPoint)
        Dim recvMsg As String = Encoding.UTF8.GetString(recvBytes)
        '' Pass the string to a method that runs on the UI thread
        Me.BeginInvoke(New Action(Of String)(AddressOf DataReceived), recvMsg)
        '' Continue receiving
        dgClient.BeginReceive(AddressOf UDPRecv, Nothing)
    Catch ex As ObjectDisposedException
        '' Socket was closed, do nothing
    End Try
End Sub

Private Sub DataReceived(recvMsg As String)
    '' This method runs on the UI thread
    '' etc...
End Sub

Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
    '' Close the socket when the form is closed
    dgClient.Close()
End Sub