1) EndReceive
должно быть первым, что вы делаете в асинхронном обратном вызове. На самом деле, вы ничего не можете сделать в обратном вызове, пока не позвоните EndReceive
, потому что именно это дает вам данные, которые были получены. См. Пример в Socket.EndReceive .
То же самое относится и к EndAccept , поскольку он дает вам сокет, с которым вы будете общаться.
2) Вам следует позвонить BeginAccept
как можно скорее после EndAccept
. В противном случае вы рискуете пропустить запросы соединения, если ваш ответный обратный вызов занимает слишком много времени для обработки. Конечно, если ваш обратный вызов подтверждения занимает много времени, вы делаете это неправильно. Опять же, то же самое относится и к BeginReceive
: позвоните как можно скорее после EndRead
, чтобы избежать потери данных. Или, если ваш коммуникационный протокол представляет собой модель запроса / ответа, где клиент ожидает ответа перед отправкой дополнительных данных, вы можете подождать, чтобы позвонить на номер BeginRead
, пока вы не отправите ответ.
3) Обработка может быть пулом потоков .NET, хотя, если вы собираетесь использовать это, вы должны изучить использование параллельной библиотеки задач. Преимущество использования TPL состоит в том, что он очень сильно «стреляет и забывает» или, возможно, «стреляет, и он перезвонит, когда будет сделано». Недостатком использования TPL является то, что вашему приложению сложнее узнать, какие задачи ожидают выполнения. Если вы создаете собственную очередь синхронизированной обработки, вы всегда знаете, какие задания ожидают выполнения, и у вас есть возможность изучить очередь, отменить задания и т. Д. Если вы захотите сделать это с TPL, вы в конечном итоге создадите набор задач, которые вам нужно управлять, поскольку нет способа получить список ожидающих задач .
Но если вам не нужно видеть отложенные задачи, то TPL должен работать хорошо.
Связанные вопросы содержат полезную информацию.