Здравствуйте, hi_octane, Вы писали:
S>>Вопрос: как сейчас грамотнее делать APM или async? Вроде async более понятен для чтения и этот код эквивалентен 1-ому варианту APM.
S>>Правильно ли я понимаю, что в обоих случаях будет вызываться iocp-поток? Соотв. если у меня будет много подобных соединений, то и iocp-потоков
S>>должно быть много.
_>Не вижу смысла делать случай 2 по двум причинам: 1) вызовешь ты ReadAsync раньше или позже вообще никак не повлияет на доступность данных — сетевая карта сложит данные в системный буфер когда они придут, и точный момент вызова тут не особо важен 2) rc там теоретически возможен. То есть он может есть, может нет, а может он только на какой-нибудь из поддерживаемых систем появится — это всё будет зависеть от деталей реализации, и ловить будет очень сложно.
Я тут не совсем понимаю как работает сеть, но данных в буффере у меня может быть сильно больше чем 4096, соотв. после ReadAsync() во 2-м случае 2-й поток стартует практически
параллельно с 1м. Ну т.е. пока я обрабатываю (вычитал) 4096 байт из буффера, там отправитель отправит еще данные, которые будут сложены в буффер. Т.е. как
я вычитал 4096 байт, тут же там появлоись еще. Или было 8192 байт.
_>По async: внутри сокетов всё переписано на async, и все новые оптимизации продолжают делаться для async. Для .NET6 сам APM эмулируется через обёртки типа TaskToApm, так что у тебя будут и накладные расходы на async и расходы на обёртку. Короче APM разумно оставить в прошлом.
_>В большинстве случаев сейчас самое правильное использовать или уже готовый паттерн async + System.IO.Pipelines, или свой велосипед написанный по мотивам и ускоряющий какие-то специфичные для задачи сценарии.
Проект под 4.7.1