UDPClient异步回调期间传入消息会发生什么?

时间:2014-02-21 19:15:07

标签: vb.net asynchronous udpclient

因此,我们每秒有大约30条UDP消息进入,并且在每条消息上我们正在执行处理和数据库操作。我的第一个想法是完成操作,然后再次调用BeginReceive方法并让下一条消息进来。由于收到消息和再次调用BeginReceive之间有一点间隔,所以收到的消息会发生什么这个过渡期?另外,如果我在操作之前将BeginReceive移动到异步回调的开头,是否会产生各种线程复杂性甚至可以安全地进行?

Public Sub Start()
    _udpclient.BeginReceive(New AsyncCallback(AddressOf ReceiveCallback), Nothing)
End Sub

方法1:

Public Sub ReceiveCallback(ar As IAsyncResult)
    Try
        Dim bytes As Byte() = _udpclient.EndReceive(ar, _ipendpoint)
        HeavyProcessAndDBOperation(bytes)
        _udpclient.BeginReceive(New AsyncCallback(AddressOf ReceiveCallback), Nothing)
    Catch ex1 As Exception
    End Try
End Sub

方法2:

Public Sub ReceiveCallback(ar As IAsyncResult)
    Try
        Dim bytes As Byte() = _udpclient.EndReceive(ar, _ipendpoint)
        _udpclient.BeginReceive(New AsyncCallback(AddressOf ReceiveCallback), Nothing)
        HeavyProcessAndDBOperation(bytes)
    Catch ex1 As Exception
    End Try
End Sub

1 个答案:

答案 0 :(得分:1)

您希望该客户端在收到数据包后尽快再次接收数据。

如果我没记错的话,每次对ReceiveCallback的调用都将在一个单独的线程中触发,因此在你的回调中立即调用BeginReceive(根据你的方法2)就是你想要的模式。

每个ReceiveCallback会有一个被触发的线程,即:每个数据包,基本上。每个ReceiveCallback会立即向BeginReceive再触发一个帖子,这样您就可以获得尽可能多的数据。

对于临时的数据包:请记住,UDP是一种无连接协议。通过使用方法2,您将最小化但可能不会消除数据包丢失。您可能会错过EndReceiveBeginReceive之间的数据包。

如果您选择方法1,您将丢失HeavyProcessAndDBOperation()占用的时间窗口中发送的数据包数量。

ReceiveCallback个线程彼此独立,一个处理的数据不受其他人处理的数据的影响 除非它是共享字段,数据库连接等...

你可能想在这里做些什么来补救共享字段等等,而且我不知道最好的解决方案,所以拿出一些盐,就是:在每个ReceiveCallback中触发另一个线程HeavyProcessAndDBOperation。从该线程中,锁定您的实际数据库操作和共享字段处理。这将增加处理数据所需的时间,但由于它在另一个线程中,因此不会影响其他数据包的接收操作。

我不确定锁定处理块的正确方法。我曾经使用过SyncLock,但是我做完这类工作已经有几年了,所以你可能想在那里做一些研究。

希望有所帮助。