因此,我们每秒有大约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
答案 0 :(得分:1)
您希望该客户端在收到数据包后尽快再次接收数据。
如果我没记错的话,每次对ReceiveCallback
的调用都将在一个单独的线程中触发,因此在你的回调中立即调用BeginReceive
(根据你的方法2)就是你想要的模式。
每个ReceiveCallback
会有一个被触发的线程,即:每个数据包,基本上。每个ReceiveCallback
会立即向BeginReceive
再触发一个帖子,这样您就可以获得尽可能多的数据。
对于临时的数据包:请记住,UDP是一种无连接协议。通过使用方法2,您将最小化但可能不会消除数据包丢失。您可能会错过EndReceive
和BeginReceive
之间的数据包。
如果您选择方法1,您将丢失HeavyProcessAndDBOperation()
占用的时间窗口中发送的数据包数量。
ReceiveCallback
个线程彼此独立,一个处理的数据不受其他人处理的数据的影响 除非它是共享字段,数据库连接等... 强>
你可能想在这里做些什么来补救共享字段等等,而且我不知道最好的解决方案,所以拿出一些盐,就是:在每个ReceiveCallback
中触发另一个线程HeavyProcessAndDBOperation
。从该线程中,锁定您的实际数据库操作和共享字段处理。这将增加处理数据所需的时间,但由于它在另一个线程中,因此不会影响其他数据包的接收操作。
我不确定锁定处理块的正确方法。我曾经使用过SyncLock,但是我做完这类工作已经有几年了,所以你可能想在那里做一些研究。
希望有所帮助。