C# SocketAsynceventargs прекращает стрельбу за завершенное мероприятие

StackOverflow https://stackoverflow.com/questions/19824576

Вопрос

Я заметил проблему, когда. Совместное событие сокетасинценвентаргов Кажется, перестает стрелять. Анкет Тот же SAEA может стрелять должным образом и быть заменен в бассейне несколько раз, но в конечном итоге все экземпляры перестанут стрелять, и потому что код для замены их в бассейне находится в обработке событий, пул опустошает.

А Следующие обстоятельства также, очевидно, правда:

1) Похоже, что это происходит только тогда, когда сокет на стороне сервера отправляет данные одному из подключенных клиентов. Когда тот же класс подключается как клиент, он не кажется неисправной.

2) Похоже, это происходит при высокой нагрузке. Количество потоков, кажется, ползуется, пока в конце концов не произойдет ошибка.

3) Испытательная установка под аналогичным стрессом никогда не представляется неисправной. (Это всего лишь 20 сообщений в секунду, и испытательная установка была доказана до 20 тыс.)

Я не смогу вставить довольно сложный код, но вот Описание моего кода:

1) Основное вдохновение в этом: http://vadmyst.blogspot.ch/2008/05/sample-code-for-tcp-server-using.html. Анкет Он показывает, как подключить порт завершения, используя событие, как получить сообщения разных размеров по соединению TCP и так далее.

2) У меня есть байтовый буфер, в котором у всех SAEA есть кусок, который не перекрывается.

3) У меня есть объектный пул SAEAS, основанный на блокировке. Это бросает, если бассейн пуст слишком долго.

4) Как сервер, я держу коллекцию розеток, возвращаемых из функции AcceptAsync, индексированной в конечной точке клиента. Один процесс может использовать один экземпляр в качестве сервера, а также несколько экземпляров в качестве клиентов (формирование Интернета). Они делятся буфером данных и пулом SAEAS.

Я понимаю, что это трудно объяснить; Я отлаживал это целый день и ночь. Просто надеясь, что кто -то слышал об этом или имеет полезные вопросы или предложения.

На данный момент я подозреваю какое -то истощение ниток, что приводит к тому, что SAEAS не может назвать завершение. В качестве альтернативы, какая -то буферная проблема в исходящем буфере.

Это было полезно?

Решение

Итак, еще один день отладки, и, наконец, у меня есть объяснение.

1) SAEAS не стреляли в завершенное событие, потому что они не смогли отправить больше. Это раскрывается Wireshark, вызванная опустошением окна TCP. (TCP Zerowindow)

2) Окно TCP опустошило, потому что сетевой слой проходил событие в стеке, которое заняло слишком много времени для завершения, то есть нет производителя/потребителя между сетевым уровнем и пользовательским интерфейсом. Таким образом, сетевой OP должен был бы ждать рисования экрана перед отправкой ACK.

3) Событие, которое заняло слишком много времени, было рисованием экрана в обработчике событий на графическом интерфейсе. Тестовая установка представляла собой консольное окно (которое суммировало входящие сообщения), поэтому это не вызвало проблемы при гораздо более высокой нагрузке. Нормально не перерисовать экран на каждом сообщении, но это происходило, потому что проект еще не совсем сделал. Скорость перерыва была бы зафиксирована позже.

4) Краткосрочное решение состоит в том, чтобы просто убедиться, что нет графических интерфейсов, удерживающих шоу. Более надежным решением может быть создание производителя/потребителя на сетевом уровне.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top