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