F # / MailBoxProcessor не отвечает на PostAndReply под нагрузкой почти 100% - PullRequest
0 голосов
/ 14 января 2019

У меня есть MailBoxProcessor, который выполняет следующие действия:

  1. Основной цикл (type AsyncRunner: https://github.com/kkkmail/ClmFSharp/blob/master/Clm/ContGen/AsyncRun.fs#L257 - номер строки может измениться, поскольку я продолжаю обновлять код). Он генерирует несколько «моделей», компилирует каждую из них в папку, специфичную для модели, порождает их как внешние процессы, а затем каждая модель использует WCF, чтобы «сообщить» AsyncRunner о своем прогрессе, вызвав updateProgress. Для запуска модели может потребоваться несколько дней. Как только любая из моделей завершена, бегун генерирует / порождает больше. Он предназначен для работы при 100% загрузке процессора (но с приоритетом: ProcessPriorityClass.BelowNormal), хотя я могу указать меньшее количество логических ядер для использования (некоторое число от 1 до Environment.ProcessorCount). В настоящее время я "асинхронизировал" почти все, что происходит внутри MailBoxProcessor, используя … |> Async.Start, чтобы гарантировать, что я "никогда" не заблокирую основной цикл.

  2. Я могу «спросить» бегуна (используя WCF) о его состоянии, позвонив member this.getState () = messageLoop.PostAndReply GetState.

  3. ИЛИ Я могу отправить ему несколько команд (снова используя WCF), например, member this.start(), member this.stop(),…

Вот где это становится интересным. Все работает! Однако, если я запускаю «монитор», который запрашивает состояние путем эффективного вызова PostAndReply (отображается как this.getState ()) в бесконечном цикле, через некоторое время он как бы зависает. Я имею в виду, что действительно в конечном итоге возвращается, но с некоторыми непредсказуемо большими задержками (например, несколько минут). В то же время я могу давать команды, и они возвращаются быстро, в то время как getState все еще не вернулся.

Возможно ли сделать его отзывчивым при нагрузке почти 100%? Большое спасибо!

1 Ответ

0 голосов
/ 17 января 2019

Я бы посоветовал не асинхронизировать что-либо (кроме порождения процессов) в вашей основной программе, поскольку ваш код создает дополнительные процессы. Ваш главный цикл ожидает возврата цикла для продолжения перед обработкой метода GetState ().

...