我有一个使用SocketAsyncEventArgs
异步接收UDP数据包的标准实现。我不明白从文档和一些谷歌搜索是,如果我应该在回调本身内处理消息的真实工作,如我指的完整实现中的this comment indicates,或者我应该将处理卸载到其他线程,例如通过ConcurrentQueue或BlockingCollection。在哪些线程上调用SocketAsyncEventArgs完成并处理消息
我关注的是以下几点:
- 如果直接在回调处理,可以把它降低接收性能或引入由于临时线程池饥饿或其他一些实现细节随机延迟?
- 由于处理过程中的轻微延迟(而不是仅仅卸载到一个集合)可能会由于缓冲区而丢弃更多的包?
- 是否可以按照与包实际上从网络到达不同的顺序调用回调的意义来重新排序更多包。
那么,什么是最好的做法或加工使用的SocketAsyncEventArgs保证最低错过的数据报,回调调用没有额外的重新排序,没有额外的延迟消息的预期呢?
和一个相关的问题 - 是否ReceiveAsync
保证任何命令或至少尝试调用回调以相同的顺序,从网络接收包,或者我应该使用阻止接收的呢?目标用例是订阅6-8个UDP通道,其中每个通道的顺序非常重要。运行一些阻塞线程看起来比处理回调要复杂得多,但如果只有这样的解决方案可以保证消息顺序,那就不那么难。
谢谢!序列号已由外部数据源(交换)提供,并且无论如何将存在恢复顺序的逻辑,并且TCP不是一个选项。所以你说在任何意义上,循环中的阻塞读取都不比ReceiveAsync更可靠? –
_“在任何意义上来说,循环中的阻塞读取都不如ReceiveAsync可靠吗?” - “在任何意义上”都非常广泛。循环中的阻塞读取肯定可以更容易地进行正确编码,所以至少肯定它在这个“意义上”是“更可靠的”。此外,即使使用异步读取,您也可以选择一次只有一个未完成的读取操作,这在语义上与具有阻止读取的循环相同; ... –
...唯一的区别是更好的可伸缩性和缺乏线程阻塞,并且实现在某种意义上是简单的(和TCP相比,多个并发读取操作在实践中更简单)。但是,是的......从某种意义上说,对于使用UDP的情况,您必须处理乱序数据,从而引入读取完成例程相对于读取操作本身实际完成的顺序执行的可能性,比一般用_any_其他读取实现来处理UDP。 –