.NET Async Sockets: есть ли преимущество SocketAsyncEventArgs перед началом / концом в этом сценарии?

В Socket появились эти новые асинхронные методы, начиная с.NET 3.5, для использования с SocketAsyncEventArgs (например, Socket.SendAsync ()). Преимущества заключаются в том, что они используют порты завершения ввода-вывода и избегают необходимости выделять ресурсы.

Мы создали класс с именем UdpStream с простым интерфейсом - только StartSend и событие Completed. Он выделяет два SocketAsyncEventArgs, один для отправки и один для получения. StartSend просто отправляет сообщение с помощью SendAsync и вызывается примерно 10 раз в секунду. Мы используем событие Completed в принимающем SocketAsyncEventArgs, и после обработки каждого события мы все получаем AsAsc, так что он формирует цикл приема. Опять же, мы получаем примерно 10 раз в секунду.

Наша система должна поддерживать до 500 таких объектов UdpStream. Другими словами, наш сервер будет одновременно взаимодействовать с 500 различными конечными точками IP.

Я заметил в примерах MSDN SocketAsyncEventArgs, что они выделяют N x SocketAsyncEventArgs, по одному для каждой ожидающей операции приема, которую вы хотите обработать за один раз. Мне не совсем ясно, как это связано с нашим сценарием - мне кажется, что, возможно, мы не получаем преимущества от SocketAsyncEventArgs, потому что мы просто выделяем по одному на конечную точку. Если мы получим 500 SocketAsyncEventArgs, я предполагаю, что мы не получим никакой выгоды. Возможно, мы все еще получаем выгоду от портов завершения ввода-вывода?

  • Правильно ли использует этот дизайн SocketAsyncEventArgs при масштабировании до 500?

  • Для случая, когда у нас используется один "UdpStream", есть ли какое-либо преимущество использования SocketAsyncEventArgs по сравнению с более старым API Begin / End?

2 ответа

мне кажется, что, возможно, мы не получаем преимущества от SocketAsyncEventArgs, потому что мы просто выделяем по одному на конечную точку. Если мы получим 500 SocketAsyncEventArgs, я предполагаю, что мы не получим никакой выгоды.

Есть еще огромная выгода.

Если вы используете шаблон APM (методы Begin/End), каждый BeginSend и каждый BeginReceive выделить экземпляр IAsyncResult. Это означает, что полное выделение класса / объекта происходит примерно 10 000 раз в секунду (500*10 [отправить] + 500*10 [получить]). Это приводит к огромным дополнительным издержкам в системе, так как это добавит много давления ГХ.

Переключившись на новый предложенный метод для высокопроизводительных сетевых приложений, вы бы SocketAsyncEventArgs instances (500) и повторно используют их для каждого вызова метода, тем самым устраняя давление GC, создаваемое во время этих операций.

В Socket появились эти новые асинхронные методы, начиная с.NET 3.5, для использования с SocketAsyncEventArgs (например, Socket.SendAsync()). Преимущества заключаются в том, что они используют порты завершения ввода-вывода и избегают необходимости выделять ресурсы.

Методы Begin/End также используют порты завершения ввода-вывода.

Для случая, когда у нас используется один "UdpStream", есть ли какое-либо преимущество использования SocketAsyncEventArgs по сравнению с более старым API Begin/End?

Имхо вы должны придерживаться того, что вы знаете, так как вы получите продукт и работать быстрее. Но я бы также создал строгий класс обработки ввода-вывода, который заботится о транспорте. Это облегчает переход на новую модель, если транспортная эффективность оказалась узким местом.

Другие вопросы по тегам