Использовать Post или PostAndAsyncReply с MailboxProcessor F#?

Я видел разные фрагменты, демонстрирующие сообщение Put, которое возвращает unit с MailboxProcessor F#. В некоторых используется только метод Post, в то время как в других используется PostAndAsyncReply, при этом канал ответа немедленно отвечает после обработки сообщения. При проведении некоторых тестов я обнаружил значительную задержку во времени ожидания ответа, поэтому кажется, что если вам не нужен реальный ответ, вам следует использовать Post.

Примечание. Я начал спрашивать об этом в другой теме, но счел полезным опубликовать полный вопрос. В другой ветке Томас Петричек упомянул, что канал ответа можно использовать как механизм ожидания, чтобы гарантировать задержку вызывающего абонента до тех пор, пока сообщение Put не будет обработано.

Помогает ли использование PostAndAsyncReply в упорядочении сообщений, или это просто принудительная пауза, пока не будет обработано первое сообщение? С точки зрения производительности Post кажется правильным решением. Это точно?

Обновление:

Я просто подумал о причине, по которой PostAndAsyncReply может понадобиться в BlockingQueueAgent пример: Scan используется для поиска Get сообщений, когда очередь заполнена, поэтому вам не нужно Put, а затем Get до завершения предыдущего Put.


person Community    schedule 15.12.2011    source источник
comment
Разве это не сводится к тому, нужен ли вам ответ? Или я что-то упускаю?   -  person Daniel    schedule 15.12.2011
comment
поэтому кажется, что если вам не нужен реальный ответ, вы должны использовать Post. Это твой вопрос? Если так, то да. Я немного смущен тем, что вы пытаетесь понять. Вас беспокоит только производительность?   -  person gradbot    schedule 15.12.2011
comment
Вот исходник FWIW github.com/fsharp/ fsharp/blob/master/src/fsharp/FSharp.Core/   -  person gradbot    schedule 15.12.2011
comment
Я немного обновил вопрос, чтобы попытаться уточнить.   -  person    schedule 16.12.2011


Ответы (2)


Я думаю, что в целом согласен с вашим резюме - имеет смысл, что PostAndAsyncReply медленнее, чем Post, поэтому, если вызывающему абоненту не нужно получать уведомление от агента, когда операция (например, помещение значения в очередь) завершается, он должен определенно предоставьте способ сделать это, используя только Post. Тот факт, что PostAndAsyncReply намного медленнее, вероятно, означает, что некоторые агенты должны выставлять оба варианта и позволять решать вызывающей стороне.

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

Используя BlockingQueueAgent, который отправляет сообщение Put с помощью PostAndAsyncReply, мы можем дождаться, пока элемент будет добавлен в очередь асинхронно (поэтому он блокирует производителя, но не блокирует потоки!) Примером типичного использования является конвейер обработки изображений, который я написал некоторое время назад. Вот один фрагмент оттуда:

// Phase 2: Scale to a thumbnail size and add frame
let scalePipelinedImages = async {
   while true do 
     let! info = loadedImages.AsyncGet()
     scaleImage info
     do! scaledImages.AsyncAdd(info) }

Этот цикл неоднократно получает изображение из очереди loadedImages, выполняет некоторую обработку и записывает результат в scaledImages. Блокировка с использованием очереди (как при чтении, так и при записи) контролирует параллелизм, так что шаги конвейера выполняются параллельно, но не загружает все больше и больше изображений, если конвейер не может обрабатывать их с требуемой скоростью.

person Tomas Petricek    schedule 15.12.2011

Мой совет: спроектируйте свою систему так, чтобы вы могли использовать Post как можно чаще.

Эта технология была разработана для асинхронного параллелизма, целью которого является отправка и забвение сообщений. Идея ожидания ответа идет прямо вразрез с этим.

person J D    schedule 01.07.2013