Как остановить асинхронный код tcp .NET от использования ресурсов всей системы

В некотором асинхронном коде tcp-сервера, который у меня есть, иногда возникает ошибка, которая заставляет процесс использовать всю системную память. При просмотре журналов, просмотра событий и некоторыхMS документы проблема возникает, если «вызывающее приложение выполняет асинхронные вызовы ввода-вывода к одному и тому же клиенту несколько раз, тогда вы можете увидеть фрагментацию кучи и увеличение частного байта, если удаленный клиент прекратит завершать ввод-вывод»; что приводит к скачкам в использовании памяти и закреплении структуры System.Threading.OverlappedData и байтовых массивов.

Предложенное решение статьи KB состоит в том, чтобы "установить верхнюю границу количества ожидающих буферов (отправляющих или получающих) с их асинхронным вводом-выводом".

Как это сделать? Это относится к байту [], который отправляется в BeginRead? Таким образом, является ли решение простым переносом байтов [] доступа с семафором?

РЕДАКТИРОВАТЬ: контролируемый семафором доступ к байтовым буферам или просто наличие статического пула байтовых буферов - это два общих решения. Я по-прежнему обеспокоен тем, что, когда возникает эта проблема асинхронного клиента (может быть, это действительно странное сетевое событие), когда семафоры или пулы байтовых буферов не позволяют мне исчерпать память, но это не решает проблему. Мой пул буферов, вероятно, будет сожран проблемным клиентом (-ами), фактически блокируя правильную функцию легитимных клиентов.

РЕДАКТИРОВАТЬ 2: наткнулся на это великоеответ, В основном это показывает, как вручную открепить объекты. И хотя асинхронный код TCP оставляет закрепление за кулисами правил выполнения, возможно, можно переопределить это, явно закрепив каждый буфер перед использованием, затем открепив в конце блока или в конце. Я пытаюсь понять это сейчас ...

 Dirk Bester24 мая 2012 г., 01:17
Прекратите желать и просто загрузите eval или бесплатный профилировщик.stackoverflow.com/questions/3927/…
 gsscoder23 мая 2012 г., 17:27
Может быть, это хорошая причина для профилирования кода ...
 Dennis21 мая 2012 г., 15:46
Возможный дубликат:stackoverflow.com/questions/236171/…
 mikalai21 мая 2012 г., 15:53
Это об упаковке вызова BeginRead с семафором.
 kmarks223 мая 2012 г., 19:08
@giacomo Я хотел бы иметь профилировщик.

Ответы на вопрос(1)

Решение Вопроса

Одним из способов решения этой проблемы является предварительное распределение буферов и других структур данных, используемых в асинхронной связи. Если вы предварительно распределяете при запуске, фрагментации не будет, так как память естественным образом будет находиться в той же области кучи.

Я рекомендую использоватьReceiveAsync/SendAsync API добавлены в .Net 3.5 SP1, что позволяет вам кэшировать или предварительно распределять обаSocketAsyncEventArgs структура и буфер памяти хранятся вSocketAsyncEventArgs.Buffer собственность, в отличие от старшегоBeginXXX/EndXXX API, которые позволяют только кэшировать или предварительно выделить буфер памяти.

Использование старого API также повлекло за собой значительные затраты ресурсов ЦП, поскольку API снова и снова создавал внутренние структуры ввода-вывода Windows. В новом API это происходит в течениеSocketAsyncEventArgsи, таким образом, за счет объединения этих объектов стоимость процессора оплачивается только один раз.

Что касается вашего обновления при закреплении: закрепление есть по причине, а именно, чтобы предотвратить перемещение буфера GC во время дефрагментации. Открепление вручную может привести к повреждению памяти.

Ваш ответ на вопрос