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

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 ]

10 голосов
/ 30 августа 2011

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

Все еще есть огромное преимущество.

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

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

6 голосов
/ 30 августа 2011

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

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

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

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

...