我有一個使用SocketAsyncEventArgs
異步接收UDP數據包的標準實現。我不明白從文檔和一些谷歌搜索是,如果我應該在回調本身內處理消息的真實工作,如我指的完整實現中的this comment indicates,或者我應該將處理卸載到其他線程,例如通過ConcurrentQueue或BlockingCollection。在哪些線程上調用SocketAsyncEventArgs完成並處理消息
我關注的是以下幾點:
- 如果直接在回調處理,可以把它降低接收性能或引入由於臨時線程池飢餓或其他一些實現細節隨機延遲?
- 由於處理過程中的輕微延遲(而不是僅僅卸載到一個集合)可能會由於緩衝區而丟棄更多的包?
- 是否可以按照與包實際上從網絡到達不同的順序調用回調的意義來重新排序更多包。
那麼,什麼是最好的做法或加工使用的SocketAsyncEventArgs保證最低錯過的數據報,回調調用沒有額外的重新排序,沒有額外的延遲消息的預期呢?
和一個相關的問題 - 是否ReceiveAsync
保證任何命令或至少嘗試調用回調以相同的順序,從網絡接收包,或者我應該使用阻止接收的呢?目標用例是訂閱6-8個UDP通道,其中每個通道的順序非常重要。運行一些阻塞線程看起來比處理回調要複雜得多,但如果只有這樣的解決方案可以保證消息順序,那就不那麼難。
謝謝!序列號已由外部數據源(交換)提供,並且無論如何將存在恢復順序的邏輯,並且TCP不是一個選項。所以你說在任何意義上,循環中的阻塞讀取都不比ReceiveAsync更可靠? –
_「在任何意義上來說,循環中的阻塞讀取都不如ReceiveAsync可靠嗎?」 - 「在任何意義上」都非常廣泛。循環中的阻塞讀取肯定可以更容易地進行正確編碼,所以至少肯定它在這個「意義上」是「更可靠的」。此外,即使使用異步讀取,您也可以選擇一次只有一個未完成的讀取操作,這在語義上與具有阻止讀取的循環相同; ... –
...唯一的區別是更好的可伸縮性和缺乏線程阻塞,並且實現在某種意義上是簡單的(和TCP相比,多個併發讀取操作在實踐中更簡單)。但是,是的......從某種意義上說,對於使用UDP的情況,您必須處理亂序數據,從而引入讀取完成例程相對於讀取操作本身實際完成的順序執行的可能性,比一般用_any_其他讀取實現來處理UDP。 –