F# / MailBoxProcessor не отвечает на PostAndReply под нагрузкой почти 100%
У меня есть MailBoxProcessor
, который делает следующие вещи:
Основной цикл (
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
чтобы я никогда не блокировал основной цикл.Я могу "спросить" бегуна (используя WCF) о его состоянии, позвонив
member this.getState () = messageLoop.PostAndReply GetState
,ИЛИ я могу послать ему несколько команд (снова используя WCF), например
member this.start()
,member this.stop()
…
Вот где это становится интересным. Все работает! Тем не менее, если я запускаю "монитор", который будет запрашивать состояние путем эффективного вызова PostAndReply
(выставлено как this.getState ()
) в бесконечном цикле, через некоторое время он как бы зависает. Я имею в виду, что он в конечном итоге возвращается, но с некоторыми непредсказуемо большими задержками (например, несколько минут). В то же время я могу давать команды, и они быстро возвращаются, пока getState
до сих пор не вернулся.
Возможно ли сделать его отзывчивым при нагрузке почти 100%? Большое спасибо!
1 ответ
Я бы предложил не асинхронизировать что-либо (кроме порождения процессов) в вашей основной программе, поскольку ваш код создает дополнительные процессы. Ваш главный цикл ожидает возврата цикла, чтобы продолжить, прежде чем обрабатывать метод GetState().