Хорошо, чтобы сделать тяжелую обработку в асинхронных обратных вызовах? - PullRequest
7 голосов
/ 11 января 2011

Можно ли выполнять тяжелую обработку в асинхронных обратных вызовах .NET, задерживая их в течение нескольких секунд перед возвратом?Или я лишаю ОС / время работы важных ресурсов?

Например, рассмотрим TcpListener.BeginAcceptSocket.Мой обратный вызов начинается с вызова EndAcceptSocket, затем тратит время на получение данных, и только затем закрывает сокет и возвращается.Это то, как это должно было быть использовано, или я должен выполнить дополнительную обработку в моем собственном потоке?

Ответы [ 2 ]

1 голос
/ 14 января 2011

Я повторил эксперименты в статье CodeProject по этой теме и обнаружил, что результаты для .NET 4 аналогичны тем, что были описаны в 2003 году. Обратите внимание, что в статье фактически не перечислялись результаты дляпроблемный раздел, но, насколько я понимаю, основная проблема все еще существует.

Я повторно использовал код из статьи CodeProject - просто загрузите его, чтобы запустить этот тест самостоятельно или экспериментировать.

Тест попытаетсяиспользовать 10 параллельных потоков для подсчета как можно большего за 1 секунду.

Использование 10 фоновых потоков (т. е. new Thread())

T0 = 4451756
T1 = 4215159
T2 = 5449189
T3 = 6244135
T4 = 3297895
T5 = 5302370
T6 = 5256763
T7 = 3779166
T8 = 6309599
T9 = 6236041
Total = 50542073

Использование 10 рабочих элементов ThreadPool

T0 = 23335890
T1 = 20998989
T2 = 22920781
T3 = 9802624
T4 = 0
T5 = 0
T6 = 0
T7 = 0
T8 = 0
T9 = 0
Total = 77058284

Обратите внимание, что только 4 рабочих элемента пула потоков из 10 когда-либо фактически выполнялись в течение 1-секундного отрезка времени! Это на четырех-основной процессор, так что это был один поток на ядро.Другие задачи, выполненные после того, как первые четыре выполнены, и, поскольку выделенная 1 секунда уже истекла, они не увеличивают свои счетчики.

Вывод: с длинными задачами, ThreadPool заставит некоторые задачи ждать позадиДругие! Таким образом, я настоятельно рекомендую не выполнять длительную обработку в задачах ThreadPool (например, обработчики асинхронного завершения).В противном случае вы можете помешать завершению более важных асинхронных вызовов, если ваша обработка данных перегружает ЦП, или у вас может быть очень нестабильная производительность, если только некоторые задачи делают много обработки.

T0 = 7175934
T1 = 6983639
T2 = 5306292
T3 = 5078502
T4 = 3279956
T5 = 8116320
T6 = 3262403
T7 = 7678457
T8 = 8946761
T9 = 8500619
Total = 64328883
1 голос
/ 11 января 2011

Да, именно так разработаны асинхронные сокеты (Tcp-клиент, слушатели и т. Д.).Вы всегда должны убедиться, что вызываете метод end aysnc, а затем выполняете любую обработку, какую пожелаете.Не вызывая методы EndAccept (), EndSEnd (), EndReceive () и т. Д., И т. Д., Вы потенциально открыты для утечки памяти, поэтому всегда рекомендуется следовать.

Используемые потокиничем не отличаются от того, если бы вы вручную наматывали фоновый поток, и на самом деле они предназначены для использования даже в «длительных операциях» в течение нескольких секунд.Поверьте мне, вы не хотите, чтобы все, что занимает столько времени, выполнялось в потоке диспетчеризации или графического интерфейса.

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

Я делаю то же самое в коде моего сервера (смешанного с некоторымидругие WCF для связующего ПО и бэкэнда), и это самый масштабируемый комм, который мы использовали.Вам придется использовать Google для этого, но есть парень, который опубликовал свое тестирование с использованием этой технологии, и он смог поддерживать 1000 одновременных подключений к серверу всего с 11 потоками.Неплохо.

Пример сервера от MS: http://msdn.microsoft.com/en-us/library/fx6588te.aspx

Пример клиента от MS: http://msdn.microsoft.com/en-us/library/bew39x2a.aspx

Требуется больше, чем это, чтобы "улучшить", но этоэто хорошее место для начала.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...