UdpClient.BeginReceive与UdpClient.Receive在一个单独的线程上

时间:2014-08-01 19:28:00

标签: c# multithreading sockets

有一个类似的问题When should I use UdpClient.BeginReceive? When should I use UdpClient.Receive on a background thread? Marc Gravell在那篇文章中写道 “异步方法的另一个优点是,您始终可以获取所需的数据,排队另一个异步提取,然后在现有异步线程上处理新数据,为并行提供更多选项(一次读取,一次处理)。”

你能举个例子说明你的意思吗?

我的问题是我正在收听UDP数据包,但我没有时间在接收线程中处理它们,因为我想尽快返回到我的接收,以免在此期间丢失任何数据包(正在套接字将丢弃我没有收到的任何数据包,因为它不是TCP)这是最好的方法吗?

1 个答案:

答案 0 :(得分:0)

使用异步IO,您可以在启动IO过程后立即返回调用方。由于IO绑定工作的性质是通过操作系统异步完成的,因此我们可以利用这一点。

当您在另一个线程上使用阻塞api(如UdpClient.Recieve)时,为了使您的应用程序保持响应,该线程将主要阻止等待UdpClient完成其接收方法。使用async IO,如标记所述,您可以释放线程,直到IO操作完成并同时执行不同的工作。

例如,我们可以使用UdpClient.RecieveAsync,它会返回Task<UdpRecieveResult>。由于任务是awaitable(有关等待的更多内容,请参阅this),我们可以利用异步io:

public async Task RecieveAndDoWorkAsync()
{
     var udpClient = new UdpClient(); // Initialize client

     var recieveTask = udpclient.RecieveAsync();

     // Do some more work

     // Wait for the operation to complete, meanwhile returning control to tge calling method (without creating any new threads)
     await recieveTask  
}