BeginReceive/SocketAsyncEventArgs список ArraySegments
В чем причина передачи списка ArraySegment<byte>
в Socket.BeginReceive
/ SocketAsyncEventArgs
?
MSDN для Socket.BeginReceive
конструктор даже не правильно описывает первый аргумент):
public IAsyncResult BeginReceive(
IList<ArraySegment<byte>> buffers,
SocketFlags socketFlags,
AsyncCallback callback,
object state
)
: параметры при
буферы
Тип:System.Collections.Generic.IList<ArraySegment<Byte>>
Массив типаByte
это место хранения полученных данных.
...
Я подумал, что основной идеей было выделить большой буфер в куче больших объектов, а затем передать сегмент этого буфера Socket.BeginReceive
, чтобы не приколоть маленькие предметы вокруг кучи и не испортить работу GC.
Но почему я должен хотеть передать несколько сегментов этим методам? В случае SocketAsyncEventArgs
Похоже, это усложнит объединение этих объектов, и я не вижу причины этого.
1 ответ
Что я узнал в этом вопросе и в MSDN:
Есть перегруженная версия
BeginReceive
это занимает байтовый массив. Когда он заполнен или пакет получен (логически по порядку), выполняется обратный вызов.Как указано в ответе, я связал:
Чтения могут быть кратны этому, потому что, если пакеты поступают не по порядку, все они становятся видимыми для приложения в момент поступления логически первого из них. В этом случае вы можете одновременно читать все смежные пакеты в очереди.
Это означает: если есть входящий пакет, который не в порядке (то есть с более высоким порядковым номером, чем ожидаемый), он будет сохранен обратно. Как только пропущенный пакет прибыл, все доступные пакеты записываются в ваш список и запускается только один обратный вызов вместо того, чтобы вызывать обратный вызов снова и снова для всех пакетов, уже доступных, каждый заполняя ваш буфер настолько, насколько это возможно, и так далее.,
Таким образом, это означает, что эта реализация экономит много накладных расходов, предоставляя все доступные пакеты в списке массивов, вызывая обратный вызов только один раз, вместо того, чтобы делать много memcopies из сетевого стека в ваш буфер и многократно вызывать вас обратным вызовом.