Функция делегата с IAsyncResult - PullRequest
0 голосов
/ 23 мая 2018

Мне было поручено принять старый бит кода, который использует делегаты.

SearchDelegate[] dlgt = new SearchDelegate[numSearches];
IAsyncResult[] ar = new IAsyncResult[numSearches];

Затем выполняется цикл для запуска нескольких функций делегата

for (int i = 0; i < numSearches; i++)
{
    ar[i] = dlgt[i].BeginInvoke(....);
}

Затем выполняетсясинхронизированный цикл для получения результатов от объекта ar.

Кажется, все работает нормально.Проблема, с которой я сталкиваюсь, заключается в том, что иногда некоторым из этих функций делегата может потребоваться от 3 до 4 секунд для запуска, даже дольше, если счет превышает 10. Это обычная проблема или есть настройка, которую я могу настроить?

Это работает на IIS.Я могу повторить проблему локально с использованием минимальных машинных ресурсов.

Спасибо всем.

Daz

Ответы [ 2 ]

0 голосов
/ 23 мая 2018

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

Некоторая дополнительная информация может быть найдена здесь Управляемый пул потоков и там Простое описание рабочих потоков и потоков ввода-вывода в сети , а также в разделе замечаний этой статьи ThreadPool.SetMinThreads .

Вы должны знать, что один и тот же пул потоков используется для обработки HTTP-запросов, поэтому обычно бессмысленно выгружать пользовательскую работу без привязки к IO в пул потоков в веб-приложениях,поскольку это не даст вам никаких преимуществ и может даже снизить производительность из-за дополнительных переключателей потоков.Хотя BeginInvoke не выглядит как вызов асинхронной операции ввода-вывода.

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

Возможно, вы захотите проверить эту тему для получения дополнительной информации по этой теме.Это связано с Task, но это не имеет значения, поскольку оба BeginInvoke и Task.Run используют один и тот же пул потоков под капотом.

0 голосов
/ 23 мая 2018

может занять от 3 до 4 секунд для запуска

вызвано пулом потоков.Когда все потоки заняты, он только медленно (2 в секунду) создает новые потоки.

Вы можете увеличить минимальное количество потоков в пуле, но особенно для веб-приложения вы должны тщательно исследовать, тестировать и измерять это.ASP.NET также является большой заинтересованной стороной в пуле потоков.

...