如何确保UDPClient接收回调在单独的线程上处理消息?

时间:2016-04-15 20:46:34

标签: .net vb.net multithreading thread-safety udpclient

我试图弄清楚如何将UDPClient接收回调与接收消息的处理分开。由于大量的UDP消息进入,我们希望将消息的实际处理转移到另一个线程,希望减轻UDP客户端的负担,不要错过任何传入的消息。 (200条消息/秒)

AsyncCallBack是否出现在UDPClient所在的同一个线程上或新线程上?如果它在同一个线程上,那么如果我在回调中创建一个新线程,我将为每个消息创建一个单独的线程,这是行不通的。 如果AsyncCallback与连接在同一个线程上,那么我的想法是我必须以某种方式在建立连接之前创建一个线程,然后在每个收到的消息上调用该线程上的某些东西?

Private Sub OpenConnection()
    _ipendpoint = New IPEndPoint(IPAddress.Any, _configobj.port)
    _udpclient = New UdpClient(_ipendpoint)
    _udpclient.BeginReceive(New AsyncCallback(AddressOf ReceiveCallback), Nothing)
End Sub

Private Sub ReceiveCallback(ar As IAsyncResult)
    Dim bytes As Byte() = _udpclient.EndReceive(ar, _ipendpoint)
    _udpclient.BeginReceive(New AsyncCallback(AddressOf ReceiveCallback), Nothing)
    ProcessReceived(bytes)
End Sub

Private Sub ProcessReceived(bytes() As Byte)
    Dim rcv As String = Encoding.ASCII.GetString(bytes).Trim()
    'PROCESS MESSAGE ON DIFFERENT THREAD
End Sub

1 个答案:

答案 0 :(得分:1)

你过度复杂化了一些事情。每秒200条消息不算什么。

首先,你需要一个阅读循环:

while (true) {
 var result = udpClient.Receive(...);
 Task.Run(() => ProcessPacketAsync(result));
}

这就是全部。您需要实施ProcessPacketAsync。根据您需要使用什么功能,它使用异步IO。通常,同步IO就足够了。使用异步IO的主要原因是在存在大量并发操作时保存线程。

你问这些东西在哪些线程上运行。这没关系,但答案是:在一些线程池线程上。